Author: cperciva
Date: Tue Dec  7 23:33:20 2010
New Revision: 216280
URL: http://svn.freebsd.org/changeset/base/216280

Log:
  Postpone the unmasking of event channels (aka. interrupts) until after
  the interrupt handlers have been registered.  NULL isn't a very good
  interrupt handler.

Modified:
  head/sys/xen/evtchn/evtchn.c

Modified: head/sys/xen/evtchn/evtchn.c
==============================================================================
--- head/sys/xen/evtchn/evtchn.c        Tue Dec  7 23:19:49 2010        
(r216279)
+++ head/sys/xen/evtchn/evtchn.c        Tue Dec  7 23:33:20 2010        
(r216280)
@@ -256,7 +256,7 @@ find_unbound_irq(void)
 }
 
 static int
-bind_caller_port_to_irq(unsigned int caller_port)
+bind_caller_port_to_irq(unsigned int caller_port, int * port)
 {
         int irq;
 
@@ -271,7 +271,7 @@ bind_caller_port_to_irq(unsigned int cal
         }
 
         irq_bindcount[irq]++;
-       unmask_evtchn(caller_port);
+       *port = caller_port;
 
  out:
         mtx_unlock_spin(&irq_mapping_update_lock);
@@ -279,7 +279,7 @@ bind_caller_port_to_irq(unsigned int cal
 }
 
 static int
-bind_local_port_to_irq(unsigned int local_port)
+bind_local_port_to_irq(unsigned int local_port, int * port)
 {
         int irq;
 
@@ -298,7 +298,7 @@ bind_local_port_to_irq(unsigned int loca
         evtchn_to_irq[local_port] = irq;
         irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
         irq_bindcount[irq]++;
-       unmask_evtchn(local_port);
+       *port = local_port;
 
  out:
         mtx_unlock_spin(&irq_mapping_update_lock);
@@ -306,7 +306,7 @@ bind_local_port_to_irq(unsigned int loca
 }
 
 static int
-bind_listening_port_to_irq(unsigned int remote_domain)
+bind_listening_port_to_irq(unsigned int remote_domain, int * port)
 {
         struct evtchn_alloc_unbound alloc_unbound;
         int err;
@@ -317,12 +317,12 @@ bind_listening_port_to_irq(unsigned int 
         err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
                                           &alloc_unbound);
 
-        return err ? : bind_local_port_to_irq(alloc_unbound.port);
+        return err ? : bind_local_port_to_irq(alloc_unbound.port, port);
 }
 
 static int
 bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
-    unsigned int remote_port)
+    unsigned int remote_port, int * port)
 {
         struct evtchn_bind_interdomain bind_interdomain;
         int err;
@@ -333,11 +333,11 @@ bind_interdomain_evtchn_to_irq(unsigned 
         err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
                                           &bind_interdomain);
 
-        return err ? : bind_local_port_to_irq(bind_interdomain.local_port);
+        return err ? : bind_local_port_to_irq(bind_interdomain.local_port, 
port);
 }
 
 static int 
-bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+bind_virq_to_irq(unsigned int virq, unsigned int cpu, int * port)
 {
        struct evtchn_bind_virq bind_virq;
        int evtchn = 0, irq;
@@ -363,7 +363,7 @@ bind_virq_to_irq(unsigned int virq, unsi
        }
 
        irq_bindcount[irq]++;
-       unmask_evtchn(evtchn);
+       *port = evtchn;
 out:
        mtx_unlock_spin(&irq_mapping_update_lock);
 
@@ -371,10 +371,8 @@ out:
 }
 
 
-extern int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu);
-
-int 
-bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
+static int 
+bind_ipi_to_irq(unsigned int ipi, unsigned int cpu, int * port)
 {
        struct evtchn_bind_ipi bind_ipi;
        int irq;
@@ -398,7 +396,7 @@ bind_ipi_to_irq(unsigned int ipi, unsign
                bind_evtchn_to_cpu(evtchn, cpu);
        }
        irq_bindcount[irq]++;
-       unmask_evtchn(evtchn);
+       *port = evtchn;
 out:
        
        mtx_unlock_spin(&irq_mapping_update_lock);
@@ -449,9 +447,10 @@ bind_caller_port_to_irqhandler(unsigned 
     unsigned long irqflags, unsigned int *irqp)
 {
        unsigned int irq;
+       int port = -1;
        int error;
 
-       irq = bind_caller_port_to_irq(caller_port);
+       irq = bind_caller_port_to_irq(caller_port, &port);
        intr_register_source(&xp->xp_pins[irq].xp_intsrc);
        error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
            &xp->xp_pins[irq].xp_cookie);
@@ -460,6 +459,8 @@ bind_caller_port_to_irqhandler(unsigned 
                unbind_from_irq(irq);
                return (error);
        }
+       if (port != -1)
+               unmask_evtchn(port);
 
        if (irqp)
                *irqp = irq;
@@ -473,9 +474,10 @@ bind_listening_port_to_irqhandler(unsign
     unsigned long irqflags, unsigned int *irqp)
 {
        unsigned int irq;
+       int port = -1;
        int error;
 
-       irq = bind_listening_port_to_irq(remote_domain);
+       irq = bind_listening_port_to_irq(remote_domain, &port);
        intr_register_source(&xp->xp_pins[irq].xp_intsrc);
        error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
            &xp->xp_pins[irq].xp_cookie);
@@ -483,6 +485,8 @@ bind_listening_port_to_irqhandler(unsign
                unbind_from_irq(irq);
                return (error);
        }
+       if (port != -1)
+               unmask_evtchn(port);
        if (irqp)
                *irqp = irq;
        
@@ -496,9 +500,10 @@ bind_interdomain_evtchn_to_irqhandler(un
     unsigned int *irqp)
 {
        unsigned int irq;
+       int port = -1;
        int error;
 
-       irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
+       irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port, &port);
        intr_register_source(&xp->xp_pins[irq].xp_intsrc);
        error = intr_add_handler(devname, irq, NULL, handler, arg,
            irqflags, &xp->xp_pins[irq].xp_cookie);
@@ -506,6 +511,8 @@ bind_interdomain_evtchn_to_irqhandler(un
                unbind_from_irq(irq);
                return (error);
        }
+       if (port != -1)
+               unmask_evtchn(port);
 
        if (irqp)
                *irqp = irq;
@@ -518,9 +525,10 @@ bind_virq_to_irqhandler(unsigned int vir
     void *arg, unsigned long irqflags, unsigned int *irqp)
 {
        unsigned int irq;
+       int port = -1;
        int error;
 
-       irq = bind_virq_to_irq(virq, cpu);
+       irq = bind_virq_to_irq(virq, cpu, &port);
        intr_register_source(&xp->xp_pins[irq].xp_intsrc);
        error = intr_add_handler(devname, irq, filter, handler,
            arg, irqflags, &xp->xp_pins[irq].xp_cookie);
@@ -528,6 +536,8 @@ bind_virq_to_irqhandler(unsigned int vir
                unbind_from_irq(irq);
                return (error);
        }
+       if (port != -1)
+               unmask_evtchn(port);
 
        if (irqp)
                *irqp = irq;
@@ -540,9 +550,10 @@ bind_ipi_to_irqhandler(unsigned int ipi,
     unsigned long irqflags, unsigned int *irqp)
 {
        unsigned int irq;
+       int port = -1;
        int error;
        
-       irq = bind_ipi_to_irq(ipi, cpu);
+       irq = bind_ipi_to_irq(ipi, cpu, &port);
        intr_register_source(&xp->xp_pins[irq].xp_intsrc);
        error = intr_add_handler(devname, irq, filter, NULL,
            NULL, irqflags, &xp->xp_pins[irq].xp_cookie);
@@ -550,6 +561,8 @@ bind_ipi_to_irqhandler(unsigned int ipi,
                unbind_from_irq(irq);
                return (error);
        }
+       if (port != -1)
+               unmask_evtchn(port);
 
        if (irqp)
                *irqp = irq;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to