From b20c19bc667aef513fa9f5449df2d4a833e42d3d Mon Sep 17 00:00:00 2001 From: kmacy Date: Thu, 23 Oct 2008 07:20:43 +0000 Subject: Fix IPI support --- sys/xen/evtchn/evtchn.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'sys/xen/evtchn') diff --git a/sys/xen/evtchn/evtchn.c b/sys/xen/evtchn/evtchn.c index 53b41ac..155b38e 100644 --- a/sys/xen/evtchn/evtchn.c +++ b/sys/xen/evtchn/evtchn.c @@ -18,6 +18,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -26,6 +27,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include @@ -113,13 +115,14 @@ enum { #define type_from_irq(irq) ((uint8_t)(irq_info[irq] >> 24)) /* IRQ <-> VIRQ mapping. */ -DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1}; /* IRQ <-> IPI mapping. */ -#ifndef NR_IPIS +#ifndef NR_IPIS +#ifdef SMP +#error "NR_IPIS not defined" +#endif #define NR_IPIS 1 #endif -DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) = {[0 ... NR_IPIS-1] = -1}; /* Bitmap indicating which PIRQs require Xen to be notified on unmask. */ static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)]; @@ -222,8 +225,11 @@ evtchn_do_upcall(struct trapframe *frame) void ipi_pcpu(unsigned int cpu, int vector) { - int irq = per_cpu(ipi_to_irq, cpu)[vector]; + int irq; + irq = per_cpu(ipi_to_irq, cpu)[vector]; + irq = (pcpu_find((cpu))->pc_ipi_to_irq)[vector]; + notify_remote_via_irq(irq); } @@ -331,6 +337,9 @@ bind_virq_to_irq(unsigned int virq, unsigned int cpu) mtx_lock_spin(&irq_mapping_update_lock); if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) { + if ((irq = find_unbound_irq()) < 0) + goto out; + bind_virq.virq = virq; bind_virq.vcpu = cpu; PANIC_IF(HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, @@ -338,7 +347,6 @@ bind_virq_to_irq(unsigned int virq, unsigned int cpu) evtchn = bind_virq.port; - irq = find_unbound_irq(); evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn); @@ -348,7 +356,7 @@ bind_virq_to_irq(unsigned int virq, unsigned int cpu) } irq_bindcount[irq]++; - +out: mtx_unlock_spin(&irq_mapping_update_lock); return irq; @@ -370,7 +378,6 @@ bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) PANIC_IF(HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, &bind_ipi) != 0); evtchn = bind_ipi.port; - irq = find_unbound_irq(); evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn); @@ -378,7 +385,6 @@ bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) bind_evtchn_to_cpu(evtchn, cpu); } - irq_bindcount[irq]++; out: @@ -515,15 +521,15 @@ int bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu, const char *devname, - driver_intr_t handler, + driver_filter_t filter, unsigned long irqflags) { - unsigned int irq; - int retval; - + int irq, retval; + irq = bind_ipi_to_irq(ipi, cpu); intr_register_source(&xp->xp_pins[irq].xp_intsrc); - retval = intr_add_handler(devname, irq, NULL, handler, NULL, irqflags, NULL); + retval = intr_add_handler(devname, irq, filter, NULL, + NULL, irqflags, NULL); if (retval != 0) { unbind_from_irq(irq); return -retval; @@ -760,6 +766,8 @@ notify_remote_via_irq(int irq) if (VALID_EVTCHN(evtchn)) notify_remote_via_evtchn(evtchn); + else + panic("invalid evtchn"); } /* required for support of physical devices */ @@ -810,6 +818,9 @@ xenpic_pirq_enable_intr(struct intsrc *isrc) bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE; if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) { +#ifndef XEN_PRIVILEGED_GUEST + panic("unexpected pirq call"); +#endif if (!probing_irq(irq)) /* Some failures are expected when probing. */ printf("Failed to obtain physical IRQ %d\n", irq); mtx_unlock_spin(&irq_mapping_update_lock); @@ -1037,7 +1048,7 @@ evtchn_init(void *dummy __unused) struct xenpic_intsrc *pin, *tpin; /* No VIRQ or IPI bindings. */ - for (cpu = 0; cpu < NR_CPUS; cpu++) { + for (cpu = 0; cpu < mp_ncpus; cpu++) { for (i = 0; i < NR_VIRQS; i++) per_cpu(virq_to_irq, cpu)[i] = -1; for (i = 0; i < NR_IPIS; i++) @@ -1104,7 +1115,7 @@ evtchn_init(void *dummy __unused) } } -SYSINIT(evtchn_init, SI_SUB_INTR, SI_ORDER_ANY, evtchn_init, NULL); +SYSINIT(evtchn_init, SI_SUB_INTR, SI_ORDER_MIDDLE, evtchn_init, NULL); /* * irq_mapping_update_lock: in order to allow an interrupt to occur in a critical * section, to set pcpu->ipending (etc...) properly, we -- cgit v1.1