WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] Backtrack on the new interface for reserved event-channe

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Backtrack on the new interface for reserved event-channel
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 06 Apr 2006 03:22:06 +0000
Delivery-date: Thu, 06 Apr 2006 01:37:50 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 8f7aad20b4a5ba33762db56bb7e5cb94fe24395e
# Parent  e1152d55ea314944a4256354e163058d81bfbeba
Backtrack on the new interface for reserved event-channel
ports, as binding them in user space via the evtchn driver
would be a pain. Instead extend VIRQs so they can be
classified as 'global' or 'per vcpu'. The former can only
be allocated once per guest, but can be re-bound to
an arbitrary VCPU.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c       Wed Apr  5 16:41:51 2006
+++ b/xen/arch/ia64/xen/xentime.c       Wed Apr  5 18:30:02 2006
@@ -274,6 +274,6 @@
 
 void send_timer_event(struct vcpu *v)
 {
-       send_guest_virq(v, VIRQ_TIMER);
-}
-
+       send_guest_vcpu_virq(v, VIRQ_TIMER);
+}
+
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Wed Apr  5 16:41:51 2006
+++ b/xen/arch/x86/time.c       Wed Apr  5 18:30:02 2006
@@ -916,7 +916,7 @@
 
 void send_timer_event(struct vcpu *v)
 {
-    send_guest_virq(v, VIRQ_TIMER);
+    send_guest_vcpu_virq(v, VIRQ_TIMER);
 }
 
 /*
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/common/domain.c
--- a/xen/common/domain.c       Wed Apr  5 16:41:51 2006
+++ b/xen/common/domain.c       Wed Apr  5 18:30:02 2006
@@ -137,7 +137,7 @@
         domain_relinquish_resources(d);
         put_domain(d);
 
-        send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
+        send_guest_global_virq(dom0, VIRQ_DOM_EXC);
     }
 }
 
@@ -192,7 +192,7 @@
 
     /* Don't set DOMF_shutdown until execution contexts are sync'ed. */
     if ( !test_and_set_bit(_DOMF_shutdown, &d->domain_flags) )
-        send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
+        send_guest_global_virq(dom0, VIRQ_DOM_EXC);
 
     UNLOCK_BIGLOCK(d);
 
@@ -267,7 +267,7 @@
     for_each_vcpu ( d, v )
         vcpu_sleep_nosync(v);
 
-    send_guest_virq(dom0->vcpu[0], VIRQ_DEBUGGER);
+    send_guest_global_virq(dom0, VIRQ_DEBUGGER);
 }
 
 
@@ -307,7 +307,7 @@
 
     free_domain(d);
 
-    send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
+    send_guest_global_virq(dom0, VIRQ_DOM_EXC);
 }
 
 void vcpu_pause(struct vcpu *v)
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Wed Apr  5 16:41:51 2006
+++ b/xen/common/event_channel.c        Wed Apr  5 18:30:02 2006
@@ -3,7 +3,7 @@
  * 
  * Event notifications from VIRQs, PIRQs, and other domains.
  * 
- * Copyright (c) 2003-2005, K A Fraser.
+ * Copyright (c) 2003-2006, K A Fraser.
  * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -47,6 +47,27 @@
     } while ( 0 )
 
 
+static int virq_is_global(int virq)
+{
+    int rc;
+
+    ASSERT((virq >= 0) && (virq < NR_VIRQS));
+
+    switch ( virq )
+    {
+    case VIRQ_TIMER:
+    case VIRQ_DEBUG:
+        rc = 0;
+        break;
+    default:
+        rc = 1;
+        break;
+    }
+
+    return rc;
+}
+
+
 static int get_free_port(struct domain *d)
 {
     struct evtchn *chn;
@@ -180,6 +201,9 @@
     long           rc = 0;
 
     if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
+        return -EINVAL;
+
+    if ( virq_is_global(virq) && (vcpu != 0) )
         return -EINVAL;
 
     if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || ((v = d->vcpu[vcpu]) == NULL) )
@@ -474,19 +498,43 @@
 }
 
 
-void send_guest_virq(struct vcpu *v, int virq)
-{
-    int port = v->virq_to_evtchn[virq];
-
-    if ( likely(port != 0) )
-        evtchn_set_pending(v, port);
+void send_guest_vcpu_virq(struct vcpu *v, int virq)
+{
+    int port;
+
+    ASSERT(!virq_is_global(virq));
+
+    port = v->virq_to_evtchn[virq];
+    if ( unlikely(port == 0) )
+        return;
+
+    evtchn_set_pending(v, port);
+}
+
+void send_guest_global_virq(struct domain *d, int virq)
+{
+    int port;
+    struct evtchn *chn;
+
+    ASSERT(virq_is_global(virq));
+
+    port = d->vcpu[0]->virq_to_evtchn[virq];
+    if ( unlikely(port == 0) )
+        return;
+
+    chn = evtchn_from_port(d, port);
+    evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
 }
 
 
 void send_guest_pirq(struct domain *d, int pirq)
 {
     int port = d->pirq_to_evtchn[pirq];
-    struct evtchn *chn = evtchn_from_port(d, port);
+    struct evtchn *chn;
+
+    ASSERT(port != 0);
+
+    chn = evtchn_from_port(d, port);
     evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
 }
 
@@ -576,6 +624,12 @@
     chn = evtchn_from_port(d, port);
     switch ( chn->state )
     {
+    case ECS_VIRQ:
+        if ( virq_is_global(chn->u.virq) )
+            chn->notify_vcpu_id = vcpu_id;
+        else
+            rc = -EINVAL;
+        break;
     case ECS_UNBOUND:
     case ECS_INTERDOMAIN:
     case ECS_PIRQ:
@@ -702,41 +756,6 @@
 }
 
 
-int evtchn_open_reserved_port(struct domain *d)
-{
-    struct evtchn *chn;
-    int            port;
-
-    spin_lock(&d->evtchn_lock);
-
-    if ( (port = get_free_port(d)) >= 0 )
-    {
-        chn = evtchn_from_port(d, port);
-        chn->state = ECS_RESERVED;
-    }
-
-    spin_unlock(&d->evtchn_lock);
-
-    return port;
-}
-
-
-void evtchn_close_reserved_port(struct domain *d, int port)
-{
-    struct evtchn *chn;
-
-    spin_lock(&d->evtchn_lock);
-
-    BUG_ON(!port_is_valid(d, port));
-
-    chn = evtchn_from_port(d, port);
-    chn->state          = ECS_FREE;
-    chn->notify_vcpu_id = 0;
-
-    spin_unlock(&d->evtchn_lock);
-}
-
-
 void evtchn_notify_reserved_port(struct domain *d, int port)
 {
     struct evtchn *chn = evtchn_from_port(d, port);
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c   Wed Apr  5 16:41:51 2006
+++ b/xen/common/keyhandler.c   Wed Apr  5 18:30:02 2006
@@ -162,7 +162,7 @@
                             &d->shared_info->evtchn_mask[0]),
                    test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG, 
                             &v->vcpu_info->evtchn_pending_sel));
-            send_guest_virq(v, VIRQ_DEBUG);
+            send_guest_vcpu_virq(v, VIRQ_DEBUG);
         }
     }
 
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Apr  5 16:41:51 2006
+++ b/xen/drivers/char/console.c        Wed Apr  5 18:30:02 2006
@@ -294,7 +294,7 @@
     if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
         serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c;
     /* Always notify the guest: prevents receive path from getting stuck. */
-    send_guest_virq(dom0->vcpu[0], VIRQ_CONSOLE);
+    send_guest_global_virq(dom0, VIRQ_CONSOLE);
 }
 
 static void serial_rx(char c, struct cpu_user_regs *regs)
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Wed Apr  5 16:41:51 2006
+++ b/xen/include/public/event_channel.h        Wed Apr  5 18:30:02 2006
@@ -50,9 +50,13 @@
  * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
  * vcpu.
  * NOTES:
- *  1. A virtual IRQ may be bound to at most one event channel per vcpu.
- *  2. The allocated event channel is bound to the specified vcpu. The binding
- *     may not be changed.
+ *  1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list
+ *     in xen.h for the classification of each VIRQ.
+ *  2. Global VIRQs must be allocated on VCPU0 but can subsequently be
+ *     re-bound via EVTCHNOP_bind_vcpu.
+ *  3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu.
+ *     The allocated event channel is bound to the specified vcpu and the
+ *     binding cannot be changed.
  */
 #define EVTCHNOP_bind_virq        1
 typedef struct evtchn_bind_virq {
@@ -152,9 +156,11 @@
  * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
  * event is pending.
  * NOTES:
- *  1. IPI- and VIRQ-bound channels always notify the vcpu that initialised
- *     the binding. This binding cannot be changed.
- *  2. All other channels notify vcpu0 by default. This default is set when
+ *  1. IPI-bound channels always notify the vcpu specified at bind time.
+ *     This binding cannot be changed.
+ *  2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time.
+ *     This binding cannot be changed.
+ *  3. All other channels notify vcpu0 by default. This default is set when
  *     the channel is allocated (a port that is freed and subsequently reused
  *     has its binding reset to vcpu0).
  */
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Wed Apr  5 16:41:51 2006
+++ b/xen/include/public/xen.h  Wed Apr  5 18:30:02 2006
@@ -65,12 +65,17 @@
  * VIRTUAL INTERRUPTS
  * 
  * Virtual interrupts that a guest OS may receive from Xen.
- */
-#define VIRQ_TIMER      0  /* Timebase update, and/or requested timeout.  */
-#define VIRQ_DEBUG      1  /* Request guest to dump debug info.           */
-#define VIRQ_CONSOLE    2  /* (DOM0) Bytes received on emergency console. */
-#define VIRQ_DOM_EXC    3  /* (DOM0) Exceptional event for some domain.   */
-#define VIRQ_DEBUGGER   6  /* (DOM0) A domain has paused for debugging.   */
+ * 
+ * In the side comments, 'V.' denotes a per-VCPU VIRQ while 'G.' denotes a
+ * global VIRQ. The former can be bound once per VCPU and cannot be re-bound.
+ * The latter can be allocated only once per guest: they must initially be
+ * allocated to VCPU0 but can subsequently be re-bound.
+ */
+#define VIRQ_TIMER      0  /* V. Timebase update, and/or requested timeout.  */
+#define VIRQ_DEBUG      1  /* V. Request guest to dump debug info.           */
+#define VIRQ_CONSOLE    2  /* G. (DOM0) Bytes received on emergency console. */
+#define VIRQ_DOM_EXC    3  /* G. (DOM0) Exceptional event for some domain.   */
+#define VIRQ_DEBUGGER   6  /* G. (DOM0) A domain has paused for debugging.   */
 #define NR_VIRQS        8
 
 /*
diff -r e1152d55ea31 -r 8f7aad20b4a5 xen/include/xen/event.h
--- a/xen/include/xen/event.h   Wed Apr  5 16:41:51 2006
+++ b/xen/include/xen/event.h   Wed Apr  5 18:30:02 2006
@@ -3,7 +3,7 @@
  * 
  * A nice interface for passing asynchronous events to guest OSes.
  * 
- * Copyright (c) 2002-2005, K A Fraser
+ * Copyright (c) 2002-2006, K A Fraser
  */
 
 #ifndef __XEN_EVENT_H__
@@ -18,11 +18,18 @@
 extern void evtchn_set_pending(struct vcpu *v, int port);
 
 /*
- * send_guest_virq:
+ * send_guest_vcpu_virq: Notify guest via a per-VCPU VIRQ.
  *  @v:        VCPU to which virtual IRQ should be sent
  *  @virq:     Virtual IRQ number (VIRQ_*)
  */
-extern void send_guest_virq(struct vcpu *v, int virq);
+extern void send_guest_vcpu_virq(struct vcpu *v, int virq);
+
+/*
+ * send_guest_global_virq: Notify guest via a global VIRQ.
+ *  @d:        Domain to which virtual IRQ should be sent
+ *  @virq:     Virtual IRQ number (VIRQ_*)
+ */
+extern void send_guest_global_virq(struct domain *d, int virq);
 
 /*
  * send_guest_pirq:
@@ -45,9 +52,4 @@
 /* Bind a local event-channel port to the specified VCPU. */
 extern long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
 
-/* Reserved event-channel ports for other Xen subsystems. */
-int evtchn_open_reserved_port(struct domain *d);
-void evtchn_close_reserved_port(struct domain *d, int port);
-void evtchn_notify_reserved_port(struct domain *d, int port);
-
 #endif /* __XEN_EVENT_H__ */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Backtrack on the new interface for reserved event-channel, Xen patchbot -unstable <=