svn commit: r216280 - head/sys/xen/evtchn

Colin Percival cperciva at FreeBSD.org
Tue Dec 7 23:33:21 UTC 2010


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;


More information about the svn-src-all mailing list