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] Fix unmask_evtchn() when the port is bound to a differen

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix unmask_evtchn() when the port is bound to a different
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 13 Dec 2005 19:38:15 +0000
Delivery-date: Tue, 13 Dec 2005 19:40:47 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/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 455b2b93542c728b88aba30de3e95c7d06d20ade
# Parent  62d9ac63e7f509328815443d8604f849b64d0c9d
Fix unmask_evtchn() when the port is bound to a different
VCPU.

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

diff -r 62d9ac63e7f5 -r 455b2b93542c 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Dec 13 18:08:26 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Dec 13 18:20:29 2005
@@ -639,6 +639,44 @@
 }
 EXPORT_SYMBOL(notify_remote_via_irq);
 
+void mask_evtchn(int port)
+{
+       shared_info_t *s = HYPERVISOR_shared_info;
+       synch_set_bit(port, &s->evtchn_mask[0]);
+}
+EXPORT_SYMBOL(mask_evtchn);
+
+void unmask_evtchn(int port)
+{
+       shared_info_t *s = HYPERVISOR_shared_info;
+       unsigned int cpu = smp_processor_id();
+       vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
+
+       /* Slow path (hypercall) if this is a non-local port. */
+       if (unlikely(cpu != cpu_from_evtchn(port))) {
+               evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
+                                  .u.unmask.port = port };
+               (void)HYPERVISOR_event_channel_op(&op);
+               return;
+       }
+
+       synch_clear_bit(port, &s->evtchn_mask[0]);
+
+       /*
+        * The following is basically the equivalent of 'hw_resend_irq'. Just
+        * like a real IO-APIC we 'lose the interrupt edge' if the channel is
+        * masked.
+        */
+       if (synch_test_bit(port, &s->evtchn_pending[0]) && 
+           !synch_test_and_set_bit(port / BITS_PER_LONG,
+                                   &vcpu_info->evtchn_pending_sel)) {
+               vcpu_info->evtchn_upcall_pending = 1;
+               if (!vcpu_info->evtchn_upcall_mask)
+                       force_evtchn_callback();
+       }
+}
+EXPORT_SYMBOL(unmask_evtchn);
+
 void irq_resume(void)
 {
        evtchn_op_t op;
diff -r 62d9ac63e7f5 -r 455b2b93542c 
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Tue Dec 13 18:08:26 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Tue Dec 13 18:20:29 2005
@@ -79,46 +79,16 @@
  */
 extern void unbind_from_irqhandler(unsigned int irq, void *dev_id);
 
-/*
- * Unlike notify_remote_via_evtchn(), this is safe to use across
- * save/restore. Notifications on a broken connection are silently dropped.
- */
-void notify_remote_via_irq(int irq);
-
 extern void irq_resume(void);
 
 /* Entry point for notifications into Linux subsystems. */
 asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
 
 /* Entry point for notifications into the userland character device. */
-void evtchn_device_upcall(int port);
+extern void evtchn_device_upcall(int port);
 
-static inline void mask_evtchn(int port)
-{
-       shared_info_t *s = HYPERVISOR_shared_info;
-       synch_set_bit(port, &s->evtchn_mask[0]);
-}
-
-static inline void unmask_evtchn(int port)
-{
-       shared_info_t *s = HYPERVISOR_shared_info;
-       vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
-
-       synch_clear_bit(port, &s->evtchn_mask[0]);
-
-       /*
-        * The following is basically the equivalent of 'hw_resend_irq'. Just
-        * like a real IO-APIC we 'lose the interrupt edge' if the channel is
-        * masked.
-        */
-       if (synch_test_bit(port, &s->evtchn_pending[0]) && 
-           !synch_test_and_set_bit(port / BITS_PER_LONG,
-                                   &vcpu_info->evtchn_pending_sel)) {
-               vcpu_info->evtchn_upcall_pending = 1;
-               if (!vcpu_info->evtchn_upcall_mask)
-                       force_evtchn_callback();
-       }
-}
+extern void mask_evtchn(int port);
+extern void unmask_evtchn(int port);
 
 static inline void clear_evtchn(int port)
 {
@@ -134,6 +104,12 @@
        (void)HYPERVISOR_event_channel_op(&op);
 }
 
+/*
+ * Unlike notify_remote_via_evtchn(), this is safe to use across
+ * save/restore. Notifications on a broken connection are silently dropped.
+ */
+extern void notify_remote_via_irq(int irq);
+
 #endif /* __ASM_EVTCHN_H__ */
 
 /*
diff -r 62d9ac63e7f5 -r 455b2b93542c xen/common/event_channel.c
--- a/xen/common/event_channel.c        Tue Dec 13 18:08:26 2005
+++ b/xen/common/event_channel.c        Tue Dec 13 18:20:29 2005
@@ -3,7 +3,7 @@
  * 
  * Event notifications from VIRQs, PIRQs, and other domains.
  * 
- * Copyright (c) 2003-2004, K A Fraser.
+ * Copyright (c) 2003-2005, 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
@@ -541,6 +541,41 @@
     return rc;
 }
 
+static long evtchn_unmask(evtchn_unmask_t *unmask)
+{
+    struct domain *d = current->domain;
+    shared_info_t *s = d->shared_info;
+    int            port = unmask->port;
+    struct vcpu   *v;
+
+    spin_lock(&d->evtchn_lock);
+
+    if ( unlikely(!port_is_valid(d, port)) )
+    {
+        spin_unlock(&d->evtchn_lock);
+        return -EINVAL;
+    }
+
+    v = d->vcpu[evtchn_from_port(d, port)->notify_vcpu_id];
+
+    /*
+     * These operations must happen in strict order. Based on
+     * include/xen/event.h:evtchn_set_pending(). 
+     */
+    if ( test_and_clear_bit(port, &s->evtchn_mask[0]) &&
+         test_bit          (port, &s->evtchn_pending[0]) &&
+         !test_and_set_bit (port / BITS_PER_LONG,
+                            &v->vcpu_info->evtchn_pending_sel) &&
+         !test_and_set_bit (0, &v->vcpu_info->evtchn_upcall_pending) )
+    {
+        evtchn_notify(v);
+    }
+
+    spin_unlock(&d->evtchn_lock);
+
+    return 0;
+}
+
 long do_event_channel_op(evtchn_op_t *uop)
 {
     long rc;
@@ -600,6 +635,10 @@
 
     case EVTCHNOP_bind_vcpu:
         rc = evtchn_bind_vcpu(&op.u.bind_vcpu);
+        break;
+
+    case EVTCHNOP_unmask:
+        rc = evtchn_unmask(&op.u.unmask);
         break;
 
     default:
diff -r 62d9ac63e7f5 -r 455b2b93542c xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Tue Dec 13 18:08:26 2005
+++ b/xen/include/public/event_channel.h        Tue Dec 13 18:20:29 2005
@@ -164,6 +164,16 @@
     uint32_t vcpu;
 } evtchn_bind_vcpu_t;
 
+/*
+ * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver
+ * a notification to the appropriate VCPU if an event is pending.
+ */
+#define EVTCHNOP_unmask           9
+typedef struct evtchn_unmask {
+    /* IN parameters. */
+    evtchn_port_t port;
+} evtchn_unmask_t;
+
 typedef struct evtchn_op {
     uint32_t cmd; /* EVTCHNOP_* */
     union {
@@ -176,6 +186,7 @@
         evtchn_send_t             send;
         evtchn_status_t           status;
         evtchn_bind_vcpu_t        bind_vcpu;
+        evtchn_unmask_t           unmask;
     } u;
 } evtchn_op_t;
 
diff -r 62d9ac63e7f5 -r 455b2b93542c xen/include/xen/event.h
--- a/xen/include/xen/event.h   Tue Dec 13 18:08:26 2005
+++ b/xen/include/xen/event.h   Tue Dec 13 18:20:29 2005
@@ -3,7 +3,7 @@
  * 
  * A nice interface for passing asynchronous events to guest OSes.
  * 
- * Copyright (c) 2002, K A Fraser
+ * Copyright (c) 2002-2005, K A Fraser
  */
 
 #ifndef __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] Fix unmask_evtchn() when the port is bound to a different, Xen patchbot -unstable <=