From 920e8e92e0abb0e76b2eafec67ff234cbd15c697 Mon Sep 17 00:00:00 2001 From: cperciva Date: Tue, 7 Dec 2010 23:33:20 +0000 Subject: Postpone the unmasking of event channels (aka. interrupts) until after the interrupt handlers have been registered. NULL isn't a very good interrupt handler. --- sys/xen/evtchn/evtchn.c | 53 ++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'sys/xen/evtchn') diff --git a/sys/xen/evtchn/evtchn.c b/sys/xen/evtchn/evtchn.c index 3832277..3ad2e2c 100644 --- a/sys/xen/evtchn/evtchn.c +++ b/sys/xen/evtchn/evtchn.c @@ -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 caller_port) } 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 caller_port) } 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 local_port) 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 local_port) } 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 remote_domain) 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 int remote_domain, 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, unsigned int cpu) } 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, unsigned int cpu) 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 int caller_port, 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 int caller_port, 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(unsigned int remote_domain, 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(unsigned int remote_domain, 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(unsigned int remote_domain, 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(unsigned int remote_domain, 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 virq, unsigned int cpu, 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 virq, unsigned int cpu, 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 int cpu, 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, unsigned int cpu, unbind_from_irq(irq); return (error); } + if (port != -1) + unmask_evtchn(port); if (irqp) *irqp = irq; -- cgit v1.1