Home | History | Annotate | Line # | Download | only in xen
      1 /*	$NetBSD: evtchn.c,v 1.100 2022/09/07 00:40:19 knakahara Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2006 Manuel Bouyer.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  *
     26  */
     27 
     28 /*
     29  *
     30  * Copyright (c) 2004 Christian Limpach.
     31  * Copyright (c) 2004, K A Fraser.
     32  * All rights reserved.
     33  *
     34  * Redistribution and use in source and binary forms, with or without
     35  * modification, are permitted provided that the following conditions
     36  * are met:
     37  * 1. Redistributions of source code must retain the above copyright
     38  *    notice, this list of conditions and the following disclaimer.
     39  * 2. Redistributions in binary form must reproduce the above copyright
     40  *    notice, this list of conditions and the following disclaimer in the
     41  *    documentation and/or other materials provided with the distribution.
     42  *
     43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     44  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     45  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     46  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     47  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     48  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     49  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     50  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     51  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     52  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     53  */
     54 
     55 
     56 #include <sys/cdefs.h>
     57 __KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.100 2022/09/07 00:40:19 knakahara Exp $");
     58 
     59 #include "opt_xen.h"
     60 #include "isa.h"
     61 #include "pci.h"
     62 
     63 #include <sys/param.h>
     64 #include <sys/cpu.h>
     65 #include <sys/kernel.h>
     66 #include <sys/systm.h>
     67 #include <sys/device.h>
     68 #include <sys/proc.h>
     69 #include <sys/kmem.h>
     70 #include <sys/reboot.h>
     71 #include <sys/mutex.h>
     72 #include <sys/interrupt.h>
     73 #include <sys/xcall.h>
     74 
     75 #include <uvm/uvm.h>
     76 
     77 #include <xen/intr.h>
     78 
     79 #include <xen/xen.h>
     80 #include <xen/hypervisor.h>
     81 #include <xen/evtchn.h>
     82 #include <xen/xenfunc.h>
     83 
     84 /* maximum number of (v)CPUs supported */
     85 #ifdef XENPV
     86 #define NBSD_XEN_MAX_VCPUS XEN_LEGACY_MAX_VCPUS
     87 #else
     88 #include <xen/include/public/hvm/hvm_info_table.h>
     89 #define NBSD_XEN_MAX_VCPUS HVM_MAX_VCPUS
     90 #endif
     91 
     92 #define	NR_PIRQS	NR_EVENT_CHANNELS
     93 
     94 /*
     95  * This lock protects updates to the following mapping and reference-count
     96  * arrays. The lock does not need to be acquired to read the mapping tables.
     97  */
     98 static kmutex_t evtchn_lock;
     99 
    100 /* event handlers */
    101 struct evtsource *evtsource[NR_EVENT_CHANNELS];
    102 
    103 /* Reference counts for bindings to event channels XXX: redo for SMP */
    104 static uint8_t evtch_bindcount[NR_EVENT_CHANNELS];
    105 
    106 /* event-channel <-> VCPU mapping for IPIs. XXX: redo for SMP. */
    107 static evtchn_port_t vcpu_ipi_to_evtch[NBSD_XEN_MAX_VCPUS];
    108 
    109 /* event-channel <-> VCPU mapping for VIRQ_TIMER.  XXX: redo for SMP. */
    110 static int virq_timer_to_evtch[NBSD_XEN_MAX_VCPUS];
    111 
    112 /* event-channel <-> VIRQ mapping. */
    113 static int virq_to_evtch[NR_VIRQS];
    114 
    115 
    116 #if defined(XENPV) && (NPCI > 0 || NISA > 0)
    117 /* event-channel <-> PIRQ mapping */
    118 static int pirq_to_evtch[NR_PIRQS];
    119 /* PIRQ needing notify */
    120 static int evtch_to_pirq_eoi[NR_EVENT_CHANNELS];
    121 int pirq_interrupt(void *);
    122 #endif /* defined(XENPV) && (NPCI > 0 || NISA > 0) */
    123 
    124 static void xen_evtchn_mask(struct pic *, int);
    125 static void xen_evtchn_unmask(struct pic *, int);
    126 static void xen_evtchn_addroute(struct pic *, struct cpu_info *, int, int, int);
    127 static void xen_evtchn_delroute(struct pic *, struct cpu_info *, int, int, int);
    128 static bool xen_evtchn_trymask(struct pic *, int);
    129 static void xen_intr_get_devname(const char *, char *, size_t);
    130 static void xen_intr_get_assigned(const char *, kcpuset_t *);
    131 static uint64_t xen_intr_get_count(const char *, u_int);
    132 
    133 struct pic xen_pic = {
    134 	.pic_name = "xenev0",
    135 	.pic_type = PIC_XEN,
    136 	.pic_vecbase = 0,
    137 	.pic_apicid = 0,
    138 	.pic_lock = __SIMPLELOCK_UNLOCKED,
    139 	.pic_hwmask = xen_evtchn_mask,
    140 	.pic_hwunmask = xen_evtchn_unmask,
    141 	.pic_addroute = xen_evtchn_addroute,
    142 	.pic_delroute = xen_evtchn_delroute,
    143 	.pic_trymask = xen_evtchn_trymask,
    144 	.pic_level_stubs = xenev_stubs,
    145 	.pic_edge_stubs = xenev_stubs,
    146 	.pic_intr_get_devname = xen_intr_get_devname,
    147 	.pic_intr_get_assigned = xen_intr_get_assigned,
    148 	.pic_intr_get_count = xen_intr_get_count,
    149 };
    150 
    151 /*
    152  * We try to stick to the traditional x86 PIC semantics wrt Xen
    153  * events.
    154  *
    155  * PIC pins exist in a global namespace which may be hierarchical, and
    156  * are mapped to a cpu bus concept called 'IRQ' numbers, which are
    157  * also global, but linear. Thus a PIC, pin tuple will always map to
    158  * an IRQ number. These tuples can alias to the same IRQ number, thus
    159  * causing IRQ "sharing". IRQ numbers can be bound to specific CPUs,
    160  * and to specific callback vector indices on the CPU called idt_vec,
    161  * which are aliases to handlers meant to run on destination
    162  * CPUs. This binding can also happen at interrupt time and resolved
    163  * 'round-robin' between all CPUs, depending on the lapic setup. In
    164  * this case, all CPUs need to have identical idt_vec->handler
    165  * mappings.
    166  *
    167  * The job of pic_addroute() is to setup the 'wiring' between the
    168  * source pin, and the destination CPU handler, ideally on a specific
    169  * CPU in MP systems (or 'round-robin').
    170  *
    171  * On Xen, a global namespace of 'events' exist, which are initially
    172  * bound to nothing. This is similar to the relationship between
    173  * realworld realworld IRQ numbers wrt PIC pins, since before routing,
    174  * IRQ numbers by themselves have no causal connection setup with the
    175  * real world. (Except for the hardwired cases on the PC Architecture,
    176  * which we ignore for the purpose of this description). However the
    177  * really important routing is from pin to idt_vec. On PIC_XEN, all
    178  * three (pic, irq, idt_vec) belong to the same namespace and are
    179  * identical. Further, the mapping between idt_vec and the actual
    180  * callback handler is setup via calls to the evtchn.h api - this
    181  * last bit is analogous to x86/idt.c:idt_vec_set() on real h/w
    182  *
    183  * For now we handle two cases:
    184  * - IPC style events - eg: timer, PV devices, etc.
    185  * - dom0 physical irq bound events.
    186  *
    187  * In the case of IPC style events, we currently externalise the
    188  * event binding by using evtchn.h functions. From the POV of
    189  * PIC_XEN ,  'pin' , 'irq' and 'idt_vec' are all identical to the
    190  * port number of the event.
    191  *
    192  * In the case of dom0 physical irq bound events, we currently
    193  * event binding by exporting evtchn.h functions. From the POV of
    194  * PIC_LAPIC/PIC_IOAPIC, the 'pin' is the hardware pin, the 'irq' is
    195  * the x86 global irq number  - the port number is extracted out of a
    196  * global array (this is currently kludgy and breaks API abstraction)
    197  * and the binding happens during pic_addroute() of the ioapic.
    198  *
    199  * Later when we integrate more tightly with x86/intr.c, we will be
    200  * able to conform better to (PIC_LAPIC/PIC_IOAPIC)->PIC_XEN
    201  * cascading model.
    202  */
    203 
    204 int debug_port = -1;
    205 
    206 /* #define IRQ_DEBUG 4 */
    207 
    208 /* http://mail-index.netbsd.org/port-amd64/2004/02/22/0000.html */
    209 #ifdef MULTIPROCESSOR
    210 
    211 /*
    212  * intr_biglock_wrapper: grab biglock and call a real interrupt handler.
    213  */
    214 
    215 int
    216 xen_intr_biglock_wrapper(void *vp)
    217 {
    218 	struct intrhand *ih = vp;
    219 	int ret;
    220 
    221 	KERNEL_LOCK(1, NULL);
    222 
    223 	ret = (*ih->ih_realfun)(ih->ih_realarg);
    224 
    225 	KERNEL_UNLOCK_ONE(NULL);
    226 
    227 	return ret;
    228 }
    229 #endif /* MULTIPROCESSOR */
    230 
    231 void
    232 events_default_setup(void)
    233 {
    234 	int i;
    235 
    236 	/* No VCPU -> event mappings. */
    237 	for (i = 0; i < NBSD_XEN_MAX_VCPUS; i++)
    238 		vcpu_ipi_to_evtch[i] = -1;
    239 
    240 	/* No VIRQ_TIMER -> event mappings. */
    241 	for (i = 0; i < NBSD_XEN_MAX_VCPUS; i++)
    242 		virq_timer_to_evtch[i] = -1;
    243 
    244 	/* No VIRQ -> event mappings. */
    245 	for (i = 0; i < NR_VIRQS; i++)
    246 		virq_to_evtch[i] = -1;
    247 
    248 #if defined(XENPV) && (NPCI > 0 || NISA > 0)
    249 	/* No PIRQ -> event mappings. */
    250 	for (i = 0; i < NR_PIRQS; i++)
    251 		pirq_to_evtch[i] = -1;
    252 	for (i = 0; i < NR_EVENT_CHANNELS; i++)
    253 		evtch_to_pirq_eoi[i] = -1;
    254 #endif /* defined(XENPV) && (NPCI > 0 || NISA > 0) */
    255 
    256 	/* No event-channel are 'live' right now. */
    257 	for (i = 0; i < NR_EVENT_CHANNELS; i++) {
    258 		evtsource[i] = NULL;
    259 		evtch_bindcount[i] = 0;
    260 		hypervisor_mask_event(i);
    261 	}
    262 
    263 }
    264 
    265 void
    266 events_init(void)
    267 {
    268 	mutex_init(&evtchn_lock, MUTEX_DEFAULT, IPL_NONE);
    269 
    270 	(void)events_resume();
    271 }
    272 
    273 bool
    274 events_resume(void)
    275 {
    276 	debug_port = bind_virq_to_evtch(VIRQ_DEBUG);
    277 
    278 	KASSERT(debug_port != -1);
    279 
    280 	aprint_verbose("VIRQ_DEBUG interrupt using event channel %d\n",
    281 	    debug_port);
    282 	/*
    283 	 * Don't call event_set_handler(), we'll use a shortcut. Just set
    284 	 * evtsource[] to a non-NULL value so that evtchn_do_event will
    285 	 * be called.
    286 	 */
    287 	evtsource[debug_port] = (void *)-1;
    288 	xen_atomic_set_bit(&curcpu()->ci_evtmask[0], debug_port);
    289 	hypervisor_unmask_event(debug_port);
    290 	x86_enable_intr();		/* at long last... */
    291 
    292 	return true;
    293 }
    294 
    295 bool
    296 events_suspend(void)
    297 {
    298 	int evtch;
    299 
    300 	x86_disable_intr();
    301 
    302 	/* VIRQ_DEBUG is the last interrupt to remove */
    303 	evtch = unbind_virq_from_evtch(VIRQ_DEBUG);
    304 
    305 	KASSERT(evtch != -1);
    306 
    307 	hypervisor_mask_event(evtch);
    308 	/* Remove the non-NULL value set in events_init() */
    309 	evtsource[evtch] = NULL;
    310 	aprint_verbose("VIRQ_DEBUG interrupt disabled, "
    311 	    "event channel %d removed\n", evtch);
    312 
    313 	return true;
    314 }
    315 
    316 unsigned int
    317 evtchn_do_event(int evtch, struct intrframe *regs)
    318 {
    319 	struct cpu_info *ci;
    320 	int ilevel;
    321 	struct intrhand *ih;
    322 	int	(*ih_fun)(void *, void *);
    323 	uint64_t iplmask;
    324 
    325 	KASSERTMSG(evtch >= 0, "negative evtch: %d", evtch);
    326 	KASSERTMSG(evtch < NR_EVENT_CHANNELS,
    327 	    "evtch number %d > NR_EVENT_CHANNELS", evtch);
    328 
    329 #ifdef IRQ_DEBUG
    330 	if (evtch == IRQ_DEBUG)
    331 		printf("evtchn_do_event: evtch %d\n", evtch);
    332 #endif
    333 	ci = curcpu();
    334 
    335 	/*
    336 	 * Shortcut for the debug handler, we want it to always run,
    337 	 * regardless of the IPL level.
    338 	 */
    339 	if (__predict_false(evtch == debug_port)) {
    340 		xen_debug_handler(NULL);
    341 		hypervisor_unmask_event(debug_port);
    342 		return 0;
    343 	}
    344 
    345 	KASSERTMSG(evtsource[evtch] != NULL, "unknown event %d", evtch);
    346 
    347 	if (evtsource[evtch]->ev_cpu != ci)
    348 		return 0;
    349 
    350 	ci->ci_data.cpu_nintr++;
    351 	evtsource[evtch]->ev_evcnt.ev_count++;
    352 	ilevel = ci->ci_ilevel;
    353 
    354 	if (evtsource[evtch]->ev_maxlevel <= ilevel) {
    355 #ifdef IRQ_DEBUG
    356 		if (evtch == IRQ_DEBUG)
    357 		    printf("evtsource[%d]->ev_maxlevel %d <= ilevel %d\n",
    358 		    evtch, evtsource[evtch]->ev_maxlevel, ilevel);
    359 #endif
    360 		hypervisor_set_ipending(evtsource[evtch]->ev_imask,
    361 					evtch >> LONG_SHIFT,
    362 					evtch & LONG_MASK);
    363 		ih = evtsource[evtch]->ev_handlers;
    364 		while (ih != NULL) {
    365 			ih->ih_pending++;
    366 			ih = ih->ih_evt_next;
    367 		}
    368 
    369 		/* leave masked */
    370 
    371 		return 0;
    372 	}
    373 	ci->ci_ilevel = evtsource[evtch]->ev_maxlevel;
    374 	iplmask = evtsource[evtch]->ev_imask;
    375 	KASSERT(ci->ci_ilevel >= IPL_VM);
    376 	KASSERT(cpu_intr_p());
    377 	x86_enable_intr();
    378 	ih = evtsource[evtch]->ev_handlers;
    379 	while (ih != NULL) {
    380 		KASSERT(ih->ih_cpu == ci);
    381 #if 0
    382 		if (ih->ih_cpu != ci) {
    383 			hypervisor_send_event(ih->ih_cpu, evtch);
    384 			iplmask &= ~(1ULL << XEN_IPL2SIR(ih->ih_level));
    385 			ih = ih->ih_evt_next;
    386 			continue;
    387 		}
    388 #endif
    389 		if (ih->ih_level <= ilevel) {
    390 #ifdef IRQ_DEBUG
    391 		if (evtch == IRQ_DEBUG)
    392 		    printf("ih->ih_level %d <= ilevel %d\n", ih->ih_level, ilevel);
    393 #endif
    394 			x86_disable_intr();
    395 			hypervisor_set_ipending(iplmask,
    396 			    evtch >> LONG_SHIFT, evtch & LONG_MASK);
    397 			/* leave masked */
    398 			while (ih != NULL) {
    399 				ih->ih_pending++;
    400 				ih = ih->ih_evt_next;
    401 			}
    402 			goto splx;
    403 		}
    404 		iplmask &= ~(1ULL << XEN_IPL2SIR(ih->ih_level));
    405 		ci->ci_ilevel = ih->ih_level;
    406 		ih->ih_pending = 0;
    407 		ih_fun = (void *)ih->ih_fun;
    408 		ih_fun(ih->ih_arg, regs);
    409 		ih = ih->ih_evt_next;
    410 	}
    411 	x86_disable_intr();
    412 	hypervisor_unmask_event(evtch);
    413 #if defined(XENPV) && (NPCI > 0 || NISA > 0)
    414 	hypervisor_ack_pirq_event(evtch);
    415 #endif /* defined(XENPV) && (NPCI > 0 || NISA > 0) */
    416 
    417 splx:
    418 	ci->ci_ilevel = ilevel;
    419 	return 0;
    420 }
    421 
    422 #define PRIuCPUID	"lu" /* XXX: move this somewhere more appropriate */
    423 
    424 /* PIC callbacks */
    425 /* pic "pin"s are conceptually mapped to event port numbers */
    426 static void
    427 xen_evtchn_mask(struct pic *pic, int pin)
    428 {
    429 	evtchn_port_t evtchn = pin;
    430 
    431 	KASSERT(pic->pic_type == PIC_XEN);
    432 	KASSERT(evtchn < NR_EVENT_CHANNELS);
    433 
    434 	hypervisor_mask_event(evtchn);
    435 }
    436 
    437 static void
    438 xen_evtchn_unmask(struct pic *pic, int pin)
    439 {
    440 	evtchn_port_t evtchn = pin;
    441 
    442 	KASSERT(pic->pic_type == PIC_XEN);
    443 	KASSERT(evtchn < NR_EVENT_CHANNELS);
    444 
    445 	hypervisor_unmask_event(evtchn);
    446 
    447 }
    448 
    449 
    450 static void
    451 xen_evtchn_addroute(struct pic *pic, struct cpu_info *ci, int pin, int idt_vec, int type)
    452 {
    453 
    454 	evtchn_port_t evtchn = pin;
    455 
    456 	/* Events are simulated as level triggered interrupts */
    457 	KASSERT(type == IST_LEVEL);
    458 
    459 	KASSERT(evtchn < NR_EVENT_CHANNELS);
    460 #if notyet
    461 	evtchn_port_t boundport = idt_vec;
    462 #endif
    463 
    464 	KASSERT(pic->pic_type == PIC_XEN);
    465 
    466 	xen_atomic_set_bit(&ci->ci_evtmask[0], evtchn);
    467 
    468 }
    469 
    470 static void
    471 xen_evtchn_delroute(struct pic *pic, struct cpu_info *ci, int pin, int idt_vec, int type)
    472 {
    473 	/*
    474 	 * XXX: In the future, this is a great place to
    475 	 * 'unbind' events to underlying events and cpus.
    476 	 * For now, just disable interrupt servicing on this cpu for
    477 	 * this pin aka cpu.
    478 	 */
    479 	evtchn_port_t evtchn = pin;
    480 
    481 	/* Events are simulated as level triggered interrupts */
    482 	KASSERT(type == IST_LEVEL);
    483 
    484 	KASSERT(evtchn < NR_EVENT_CHANNELS);
    485 #if notyet
    486 	evtchn_port_t boundport = idt_vec;
    487 #endif
    488 
    489 	KASSERT(pic->pic_type == PIC_XEN);
    490 
    491 	xen_atomic_clear_bit(&ci->ci_evtmask[0], evtchn);
    492 }
    493 
    494 /*
    495  * xen_evtchn_trymask(pic, pin)
    496  *
    497  *	If there are interrupts pending on the bus-shared pic, return
    498  *	false.  Otherwise, mask interrupts on the bus-shared pic and
    499  *	return true.
    500  */
    501 static bool
    502 xen_evtchn_trymask(struct pic *pic, int pin)
    503 {
    504 	volatile struct shared_info *s = HYPERVISOR_shared_info;
    505 	unsigned long masked __diagused;
    506 
    507 	/* Mask it.  */
    508 	masked = xen_atomic_test_and_set_bit(&s->evtchn_mask[0], pin);
    509 
    510 	/*
    511 	 * Caller is responsible for calling trymask only when the
    512 	 * interrupt pin is not masked, and for serializing calls to
    513 	 * trymask.
    514 	 */
    515 	KASSERT(!masked);
    516 
    517 	/*
    518 	 * Check whether there were any interrupts pending when we
    519 	 * masked it.  If there were, unmask and abort.
    520 	 */
    521 	if (xen_atomic_test_bit(&s->evtchn_pending[0], pin)) {
    522 		xen_atomic_clear_bit(&s->evtchn_mask[0], pin);
    523 		return false;
    524 	}
    525 
    526 	/* Success: masked, not pending.  */
    527 	return true;
    528 }
    529 
    530 evtchn_port_t
    531 bind_vcpu_to_evtch(cpuid_t vcpu)
    532 {
    533 	evtchn_op_t op;
    534 	evtchn_port_t evtchn;
    535 
    536 	mutex_spin_enter(&evtchn_lock);
    537 
    538 	evtchn = vcpu_ipi_to_evtch[vcpu];
    539 	if (evtchn == -1) {
    540 		op.cmd = EVTCHNOP_bind_ipi;
    541 		op.u.bind_ipi.vcpu = (uint32_t) vcpu;
    542 		if (HYPERVISOR_event_channel_op(&op) != 0)
    543 			panic("Failed to bind ipi to VCPU %"PRIuCPUID"\n", vcpu);
    544 		evtchn = op.u.bind_ipi.port;
    545 
    546 		vcpu_ipi_to_evtch[vcpu] = evtchn;
    547 	}
    548 
    549 	evtch_bindcount[evtchn]++;
    550 
    551 	mutex_spin_exit(&evtchn_lock);
    552 
    553 	return evtchn;
    554 }
    555 
    556 int
    557 bind_virq_to_evtch(int virq)
    558 {
    559 	evtchn_op_t op;
    560 	int evtchn;
    561 
    562 	mutex_spin_enter(&evtchn_lock);
    563 
    564 	/*
    565 	 * XXX: The only per-cpu VIRQ we currently use is VIRQ_TIMER.
    566 	 * Please re-visit this implementation when others are used.
    567 	 * Note: VIRQ_DEBUG is special-cased, and not used or bound on APs.
    568 	 * XXX: event->virq/ipi can be unified in a linked-list
    569 	 * implementation.
    570 	 */
    571 	struct cpu_info *ci = curcpu();
    572 
    573 	if (virq == VIRQ_DEBUG && ci != &cpu_info_primary) {
    574 		mutex_spin_exit(&evtchn_lock);
    575 		return -1;
    576 	}
    577 
    578 	if (virq == VIRQ_TIMER) {
    579 		evtchn = virq_timer_to_evtch[ci->ci_vcpuid];
    580 	} else {
    581 		evtchn = virq_to_evtch[virq];
    582 	}
    583 
    584 	/* Allocate a channel if there is none already allocated */
    585 	if (evtchn == -1) {
    586 		op.cmd = EVTCHNOP_bind_virq;
    587 		op.u.bind_virq.virq = virq;
    588 		op.u.bind_virq.vcpu = ci->ci_vcpuid;
    589 		if (HYPERVISOR_event_channel_op(&op) != 0)
    590 			panic("Failed to bind virtual IRQ %d\n", virq);
    591 		evtchn = op.u.bind_virq.port;
    592 	}
    593 
    594 	/* Set event channel */
    595 	if (virq == VIRQ_TIMER) {
    596 		virq_timer_to_evtch[ci->ci_vcpuid] = evtchn;
    597 	} else {
    598 		virq_to_evtch[virq] = evtchn;
    599 	}
    600 
    601 	/* Increase ref counter */
    602 	evtch_bindcount[evtchn]++;
    603 
    604 	mutex_spin_exit(&evtchn_lock);
    605 
    606 	return evtchn;
    607 }
    608 
    609 int
    610 unbind_virq_from_evtch(int virq)
    611 {
    612 	evtchn_op_t op;
    613 	int evtchn;
    614 
    615 	struct cpu_info *ci = curcpu();
    616 
    617 	if (virq == VIRQ_TIMER) {
    618 		evtchn = virq_timer_to_evtch[ci->ci_vcpuid];
    619 	}
    620 	else {
    621 		evtchn = virq_to_evtch[virq];
    622 	}
    623 
    624 	if (evtchn == -1) {
    625 		return -1;
    626 	}
    627 
    628 	mutex_spin_enter(&evtchn_lock);
    629 
    630 	evtch_bindcount[evtchn]--;
    631 	if (evtch_bindcount[evtchn] == 0) {
    632 		op.cmd = EVTCHNOP_close;
    633 		op.u.close.port = evtchn;
    634 		if (HYPERVISOR_event_channel_op(&op) != 0)
    635 			panic("Failed to unbind virtual IRQ %d\n", virq);
    636 
    637 		if (virq == VIRQ_TIMER) {
    638 			virq_timer_to_evtch[ci->ci_vcpuid] = -1;
    639 		} else {
    640 			virq_to_evtch[virq] = -1;
    641 		}
    642 	}
    643 
    644 	mutex_spin_exit(&evtchn_lock);
    645 
    646 	return evtchn;
    647 }
    648 
    649 #if defined(XENPV) && (NPCI > 0 || NISA > 0)
    650 int
    651 get_pirq_to_evtch(int pirq)
    652 {
    653 	int evtchn;
    654 
    655 	if (pirq == -1) /* Match previous behaviour */
    656 		return -1;
    657 
    658 	if (pirq >= NR_PIRQS) {
    659 		panic("pirq %d out of bound, increase NR_PIRQS", pirq);
    660 	}
    661 	mutex_spin_enter(&evtchn_lock);
    662 
    663 	evtchn = pirq_to_evtch[pirq];
    664 
    665 	mutex_spin_exit(&evtchn_lock);
    666 
    667 	return evtchn;
    668 }
    669 
    670 int
    671 bind_pirq_to_evtch(int pirq)
    672 {
    673 	evtchn_op_t op;
    674 	int evtchn;
    675 
    676 	if (pirq >= NR_PIRQS) {
    677 		panic("pirq %d out of bound, increase NR_PIRQS", pirq);
    678 	}
    679 
    680 	mutex_spin_enter(&evtchn_lock);
    681 
    682 	evtchn = pirq_to_evtch[pirq];
    683 	if (evtchn == -1) {
    684 		op.cmd = EVTCHNOP_bind_pirq;
    685 		op.u.bind_pirq.pirq = pirq;
    686 		op.u.bind_pirq.flags = BIND_PIRQ__WILL_SHARE;
    687 		if (HYPERVISOR_event_channel_op(&op) != 0)
    688 			panic("Failed to bind physical IRQ %d\n", pirq);
    689 		evtchn = op.u.bind_pirq.port;
    690 
    691 #ifdef IRQ_DEBUG
    692 		printf("pirq %d evtchn %d\n", pirq, evtchn);
    693 #endif
    694 		pirq_to_evtch[pirq] = evtchn;
    695 	}
    696 
    697 	evtch_bindcount[evtchn]++;
    698 
    699 	mutex_spin_exit(&evtchn_lock);
    700 
    701 	return evtchn;
    702 }
    703 
    704 int
    705 unbind_pirq_from_evtch(int pirq)
    706 {
    707 	evtchn_op_t op;
    708 	int evtchn = pirq_to_evtch[pirq];
    709 
    710 	mutex_spin_enter(&evtchn_lock);
    711 
    712 	evtch_bindcount[evtchn]--;
    713 	if (evtch_bindcount[evtchn] == 0) {
    714 		op.cmd = EVTCHNOP_close;
    715 		op.u.close.port = evtchn;
    716 		if (HYPERVISOR_event_channel_op(&op) != 0)
    717 			panic("Failed to unbind physical IRQ %d\n", pirq);
    718 
    719 		pirq_to_evtch[pirq] = -1;
    720 	}
    721 
    722 	mutex_spin_exit(&evtchn_lock);
    723 
    724 	return evtchn;
    725 }
    726 
    727 struct pintrhand *
    728 pirq_establish(int pirq, int evtch, int (*func)(void *), void *arg, int level,
    729     const char *intrname, const char *xname, bool known_mpsafe)
    730 {
    731 	struct pintrhand *ih;
    732 
    733 	ih = kmem_zalloc(sizeof(struct pintrhand),
    734 	    cold ? KM_NOSLEEP : KM_SLEEP);
    735 	if (ih == NULL) {
    736 		printf("pirq_establish: can't allocate handler info\n");
    737 		return NULL;
    738 	}
    739 
    740 	KASSERT(evtch > 0);
    741 
    742 	ih->pirq = pirq;
    743 	ih->evtch = evtch;
    744 	ih->func = func;
    745 	ih->arg = arg;
    746 
    747 	if (event_set_handler(evtch, pirq_interrupt, ih, level, intrname,
    748 	    xname, known_mpsafe, NULL) == NULL) {
    749 		kmem_free(ih, sizeof(struct pintrhand));
    750 		return NULL;
    751 	}
    752 
    753 	hypervisor_prime_pirq_event(pirq, evtch);
    754 	hypervisor_unmask_event(evtch);
    755 	hypervisor_ack_pirq_event(evtch);
    756 	return ih;
    757 }
    758 
    759 void
    760 pirq_disestablish(struct pintrhand *ih)
    761 {
    762 	int error = event_remove_handler(ih->evtch, pirq_interrupt, ih);
    763 	if (error) {
    764 		printf("pirq_disestablish(%p): %d\n", ih, error);
    765 		return;
    766 	}
    767 	kmem_free(ih, sizeof(struct pintrhand));
    768 }
    769 
    770 int
    771 pirq_interrupt(void *arg)
    772 {
    773 	struct pintrhand *ih = arg;
    774 	int ret;
    775 
    776 	ret = ih->func(ih->arg);
    777 #ifdef IRQ_DEBUG
    778 	if (ih->evtch == IRQ_DEBUG)
    779 	    printf("pirq_interrupt irq %d ret %d\n", ih->pirq, ret);
    780 #endif
    781 	return ret;
    782 }
    783 
    784 #endif /* defined(XENPV) && (NPCI > 0 || NISA > 0) */
    785 
    786 
    787 /*
    788  * Recalculate the interrupt from scratch for an event source.
    789  */
    790 static void
    791 intr_calculatemasks(struct evtsource *evts, int evtch, struct cpu_info *ci)
    792 {
    793 	struct intrhand *ih;
    794 	int cpu_receive = 0;
    795 
    796 	evts->ev_maxlevel = IPL_NONE;
    797 	evts->ev_imask = 0;
    798 	for (ih = evts->ev_handlers; ih != NULL; ih = ih->ih_evt_next) {
    799 		KASSERT(ih->ih_cpu == curcpu());
    800 		if (ih->ih_level > evts->ev_maxlevel)
    801 			evts->ev_maxlevel = ih->ih_level;
    802 		evts->ev_imask |= (1 << XEN_IPL2SIR(ih->ih_level));
    803 		if (ih->ih_cpu == ci)
    804 			cpu_receive = 1;
    805 	}
    806 	if (cpu_receive)
    807 		xen_atomic_set_bit(&curcpu()->ci_evtmask[0], evtch);
    808 	else
    809 		xen_atomic_clear_bit(&curcpu()->ci_evtmask[0], evtch);
    810 }
    811 
    812 
    813 struct event_set_handler_args {
    814 	struct intrhand *ih;
    815 	struct intrsource *ipls;
    816 	struct evtsource *evts;
    817 	int evtch;
    818 };
    819 
    820 /*
    821  * Called on bound CPU to handle event_set_handler()
    822  * caller (on initiating CPU) holds cpu_lock on our behalf
    823  * arg1: struct event_set_handler_args *
    824  * arg2: NULL
    825  */
    826 
    827 static void
    828 event_set_handler_xcall(void *arg1, void *arg2)
    829 {
    830 	struct event_set_handler_args *esh_args = arg1;
    831 	struct intrhand **ihp, *ih = esh_args->ih;
    832 	struct evtsource *evts = esh_args->evts;
    833 
    834 	const u_long psl = x86_read_psl();
    835 	x86_disable_intr();
    836 	/* sort by IPL order, higher first */
    837 	for (ihp = &evts->ev_handlers; *ihp != NULL;
    838 	    ihp = &((*ihp)->ih_evt_next)) {
    839 		if ((*ihp)->ih_level < ih->ih_level)
    840 			break;
    841 	}
    842 	/* insert before *ihp */
    843 	ih->ih_evt_next = *ihp;
    844 	*ihp = ih;
    845 #ifndef XENPV
    846 	evts->ev_isl->is_handlers = evts->ev_handlers;
    847 #endif
    848 	/* register per-cpu handler for spllower() */
    849 	struct cpu_info *ci = ih->ih_cpu;
    850 	int sir = XEN_IPL2SIR(ih->ih_level);
    851 	KASSERT(sir >= SIR_XENIPL_VM && sir <= SIR_XENIPL_HIGH);
    852 
    853 	KASSERT(ci == curcpu());
    854 	if (ci->ci_isources[sir] == NULL) {
    855 		KASSERT(esh_args->ipls != NULL);
    856 		ci->ci_isources[sir] = esh_args->ipls;
    857 	}
    858 	struct intrsource *ipls = ci->ci_isources[sir];
    859 	ih->ih_next = ipls->is_handlers;
    860 	ipls->is_handlers = ih;
    861 	x86_intr_calculatemasks(ci);
    862 
    863 	intr_calculatemasks(evts, esh_args->evtch, ci);
    864 	x86_write_psl(psl);
    865 }
    866 
    867 struct intrhand *
    868 event_set_handler(int evtch, int (*func)(void *), void *arg, int level,
    869     const char *intrname, const char *xname, bool mpsafe, struct cpu_info *ci)
    870 {
    871 	struct event_set_handler_args esh_args;
    872 	char intrstr_buf[INTRIDBUF];
    873 	bool bind = false;
    874 
    875 	memset(&esh_args, 0, sizeof(esh_args));
    876 
    877 	/*
    878 	 * if ci is not specified, we bind to the current cpu.
    879 	 * if ci has been proviced by the called, we assume
    880 	 * he will do the EVTCHNOP_bind_vcpu if needed.
    881 	 */
    882 	if (ci == NULL) {
    883 		ci = curcpu();
    884 		bind = true;
    885 	}
    886 
    887 
    888 #ifdef IRQ_DEBUG
    889 	printf("event_set_handler IRQ %d handler %p\n", evtch, func);
    890 #endif
    891 
    892 	KASSERTMSG(evtch >= 0, "negative evtch: %d", evtch);
    893 	KASSERTMSG(evtch < NR_EVENT_CHANNELS,
    894 	    "evtch number %d > NR_EVENT_CHANNELS", evtch);
    895 	KASSERT(xname != NULL);
    896 
    897 #if 0
    898 	printf("event_set_handler evtch %d handler %p level %d\n", evtch,
    899 	       handler, level);
    900 #endif
    901 	esh_args.ih = kmem_zalloc(sizeof (struct intrhand), KM_NOSLEEP);
    902 	if (esh_args.ih == NULL)
    903 		panic("can't allocate fixed interrupt source");
    904 
    905 
    906 	esh_args.ih->ih_pic = &xen_pic;
    907 	esh_args.ih->ih_level = level;
    908 	esh_args.ih->ih_fun = esh_args.ih->ih_realfun = func;
    909 	esh_args.ih->ih_arg = esh_args.ih->ih_realarg = arg;
    910 	esh_args.ih->ih_evt_next = NULL;
    911 	esh_args.ih->ih_next = NULL;
    912 	esh_args.ih->ih_pending = 0;
    913 	esh_args.ih->ih_cpu = ci;
    914 	esh_args.ih->ih_pin = evtch;
    915 #ifdef MULTIPROCESSOR
    916 	if (!mpsafe) {
    917 		esh_args.ih->ih_fun = xen_intr_biglock_wrapper;
    918 		esh_args.ih->ih_arg = esh_args.ih;
    919 	}
    920 #endif /* MULTIPROCESSOR */
    921 	KASSERT(mpsafe || level < IPL_HIGH);
    922 
    923 	mutex_enter(&cpu_lock);
    924 	/* allocate IPL source if needed */
    925 	int sir = XEN_IPL2SIR(level);
    926 	if (ci->ci_isources[sir] == NULL) {
    927 		struct intrsource *ipls;
    928 		ipls = kmem_zalloc(sizeof (struct intrsource), KM_NOSLEEP);
    929 		if (ipls == NULL)
    930 			panic("can't allocate fixed interrupt source");
    931 		ipls->is_recurse = xenev_stubs[level - IPL_VM].ist_recurse;
    932 		ipls->is_resume = xenev_stubs[level - IPL_VM].ist_resume;
    933 		ipls->is_pic = &xen_pic;
    934 		esh_args.ipls = ipls;
    935 		/*
    936 		 * note that we can't set ci_isources here, as
    937 		 * the assembly can't handle is_handlers being NULL
    938 		 */
    939 	}
    940 	/* register handler for event channel */
    941 	if (evtsource[evtch] == NULL) {
    942 		struct evtsource *evts;
    943 		evtchn_op_t op;
    944 		if (intrname == NULL)
    945 			intrname = intr_create_intrid(-1, &xen_pic, evtch,
    946 			    intrstr_buf, sizeof(intrstr_buf));
    947 		evts = kmem_zalloc(sizeof (struct evtsource),
    948 		    KM_NOSLEEP);
    949 		if (evts == NULL)
    950 			panic("can't allocate fixed interrupt source");
    951 
    952 		evts->ev_cpu = ci;
    953 		strlcpy(evts->ev_intrname, intrname, sizeof(evts->ev_intrname));
    954 
    955 		evcnt_attach_dynamic(&evts->ev_evcnt, EVCNT_TYPE_INTR, NULL,
    956 		    device_xname(ci->ci_dev), evts->ev_intrname);
    957 		if (bind) {
    958 			op.cmd = EVTCHNOP_bind_vcpu;
    959 			op.u.bind_vcpu.port = evtch;
    960 			op.u.bind_vcpu.vcpu = ci->ci_vcpuid;
    961 			if (HYPERVISOR_event_channel_op(&op) != 0) {
    962 				panic("Failed to bind event %d to VCPU  %s %d",
    963 				    evtch, device_xname(ci->ci_dev),
    964 				    ci->ci_vcpuid);
    965 			}
    966 		}
    967 #ifndef XENPV
    968 		evts->ev_isl = intr_allocate_io_intrsource(intrname);
    969 		evts->ev_isl->is_pic = &xen_pic;
    970 #endif
    971 		evtsource[evtch] = evts;
    972 	}
    973 	esh_args.evts = evtsource[evtch];
    974 
    975 	// append device name
    976 	if (esh_args.evts->ev_xname[0] != '\0') {
    977 		strlcat(esh_args.evts->ev_xname, ", ",
    978 		    sizeof(esh_args.evts->ev_xname));
    979 	}
    980 	strlcat(esh_args.evts->ev_xname, xname,
    981 	    sizeof(esh_args.evts->ev_xname));
    982 
    983 	esh_args.evtch = evtch;
    984 
    985 	if (ci == curcpu() || !mp_online) {
    986 		event_set_handler_xcall(&esh_args, NULL);
    987 	} else {
    988 		uint64_t where = xc_unicast(0, event_set_handler_xcall,
    989 		    &esh_args, NULL, ci);
    990 		xc_wait(where);
    991 	}
    992 
    993 	mutex_exit(&cpu_lock);
    994 	return esh_args.ih;
    995 }
    996 
    997 /*
    998  * Called on bound CPU to handle event_remove_handler()
    999  * caller (on initiating CPU) holds cpu_lock on our behalf
   1000  * arg1: evtch
   1001  * arg2: struct intrhand *ih
   1002  */
   1003 
   1004 static void
   1005 event_remove_handler_xcall(void *arg1, void *arg2)
   1006 {
   1007 	struct intrsource *ipls;
   1008 	struct evtsource *evts;
   1009 	struct intrhand **ihp;
   1010 	struct cpu_info *ci;
   1011 	struct intrhand *ih = arg2;
   1012 	int evtch = (intptr_t)(arg1);
   1013 
   1014 	evts = evtsource[evtch];
   1015 	KASSERT(evts != NULL);
   1016 	KASSERT(ih != NULL);
   1017 	ci = ih->ih_cpu;
   1018 	KASSERT(ci == curcpu());
   1019 
   1020 	const u_long psl = x86_read_psl();
   1021 	x86_disable_intr();
   1022 
   1023 	for (ihp = &evts->ev_handlers; *ihp != NULL;
   1024 	    ihp = &(*ihp)->ih_evt_next) {
   1025 		if ((*ihp) == ih)
   1026 			break;
   1027 	}
   1028 	if (*(ihp) == NULL) {
   1029 		panic("event_remove_handler_xcall: not in ev_handlers");
   1030 	}
   1031 
   1032 	*ihp = ih->ih_evt_next;
   1033 
   1034 	int sir = XEN_IPL2SIR(ih->ih_level);
   1035 	KASSERT(sir >= SIR_XENIPL_VM && sir <= SIR_XENIPL_HIGH);
   1036 	ipls = ci->ci_isources[sir];
   1037 	for (ihp = &ipls->is_handlers; *ihp != NULL; ihp = &(*ihp)->ih_next) {
   1038 		if (*ihp == ih)
   1039 			break;
   1040 	}
   1041 	if (*ihp == NULL)
   1042 		panic("event_remove_handler_xcall: not in is_handlers");
   1043 	*ihp = ih->ih_next;
   1044 	intr_calculatemasks(evts, evtch, ci);
   1045 #ifndef XENPV
   1046 	evts->ev_isl->is_handlers = evts->ev_handlers;
   1047 #endif
   1048 	if (evts->ev_handlers == NULL)
   1049 		xen_atomic_clear_bit(&ci->ci_evtmask[0], evtch);
   1050 
   1051 	x86_write_psl(psl);
   1052 }
   1053 
   1054 int
   1055 event_remove_handler(int evtch, int (*func)(void *), void *arg)
   1056 {
   1057 	struct intrhand *ih;
   1058 	struct cpu_info *ci;
   1059 	struct evtsource *evts;
   1060 
   1061 	mutex_enter(&cpu_lock);
   1062 	evts = evtsource[evtch];
   1063 	if (evts == NULL)
   1064 		return ENOENT;
   1065 
   1066 	for (ih = evts->ev_handlers; ih != NULL; ih = ih->ih_evt_next) {
   1067 		if (ih->ih_realfun == func && ih->ih_realarg == arg)
   1068 			break;
   1069 	}
   1070 	if (ih == NULL) {
   1071 		mutex_exit(&cpu_lock);
   1072 		return ENOENT;
   1073 	}
   1074 	ci = ih->ih_cpu;
   1075 
   1076 	if (ci == curcpu() || !mp_online) {
   1077 		event_remove_handler_xcall((void *)(intptr_t)evtch, ih);
   1078 	} else {
   1079 		uint64_t where = xc_unicast(0, event_remove_handler_xcall,
   1080 		    (void *)(intptr_t)evtch, ih, ci);
   1081 		xc_wait(where);
   1082 	}
   1083 
   1084 	kmem_free(ih, sizeof (struct intrhand));
   1085 	if (evts->ev_handlers == NULL) {
   1086 #ifndef XENPV
   1087 		KASSERT(evts->ev_isl->is_handlers == NULL);
   1088 		intr_free_io_intrsource(evts->ev_intrname);
   1089 #endif
   1090 		evcnt_detach(&evts->ev_evcnt);
   1091 		kmem_free(evts, sizeof (struct evtsource));
   1092 		evtsource[evtch] = NULL;
   1093 	}
   1094 	mutex_exit(&cpu_lock);
   1095 	return 0;
   1096 }
   1097 
   1098 #if defined(XENPV) && (NPCI > 0 || NISA > 0)
   1099 void
   1100 hypervisor_prime_pirq_event(int pirq, unsigned int evtch)
   1101 {
   1102 	struct physdev_irq_status_query irq_status;
   1103 	irq_status.irq = pirq;
   1104 	if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status) < 0)
   1105 		panic("HYPERVISOR_physdev_op(PHYSDEVOP_IRQ_STATUS_QUERY)");
   1106 	if (irq_status.flags & XENIRQSTAT_needs_eoi) {
   1107 		evtch_to_pirq_eoi[evtch] = pirq;
   1108 #ifdef IRQ_DEBUG
   1109 		printf("pirq %d needs notify\n", pirq);
   1110 #endif
   1111 	}
   1112 }
   1113 
   1114 void
   1115 hypervisor_ack_pirq_event(unsigned int evtch)
   1116 {
   1117 #ifdef IRQ_DEBUG
   1118 	if (evtch == IRQ_DEBUG)
   1119 		printf("%s: evtch %d\n", __func__, evtch);
   1120 #endif
   1121 
   1122 	if (evtch_to_pirq_eoi[evtch] > 0) {
   1123 		struct physdev_eoi eoi;
   1124 		eoi.irq = evtch_to_pirq_eoi[evtch];
   1125 #ifdef  IRQ_DEBUG
   1126 		if (evtch == IRQ_DEBUG)
   1127 		    printf("pirq_notify(%d)\n", evtch);
   1128 #endif
   1129 		(void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
   1130 	}
   1131 }
   1132 #endif /* defined(XENPV) && (NPCI > 0 || NISA > 0) */
   1133 
   1134 int
   1135 xen_debug_handler(void *arg)
   1136 {
   1137 	struct cpu_info *ci = curcpu();
   1138 	int i;
   1139 	int xci_ilevel = ci->ci_ilevel;
   1140 	int xci_ipending = ci->ci_ipending;
   1141 	int xci_idepth = ci->ci_idepth;
   1142 	u_long upcall_pending = ci->ci_vcpu->evtchn_upcall_pending;
   1143 	u_long upcall_mask = ci->ci_vcpu->evtchn_upcall_mask;
   1144 	u_long pending_sel = ci->ci_vcpu->evtchn_pending_sel;
   1145 	unsigned long evtchn_mask[sizeof(unsigned long) * 8];
   1146 	unsigned long evtchn_pending[sizeof(unsigned long) * 8];
   1147 
   1148 	u_long p;
   1149 
   1150 	p = (u_long)&HYPERVISOR_shared_info->evtchn_mask[0];
   1151 	memcpy(evtchn_mask, (void *)p, sizeof(evtchn_mask));
   1152 	p = (u_long)&HYPERVISOR_shared_info->evtchn_pending[0];
   1153 	memcpy(evtchn_pending, (void *)p, sizeof(evtchn_pending));
   1154 
   1155 	__insn_barrier();
   1156 	printf("debug event\n");
   1157 	printf("ci_ilevel 0x%x ci_ipending 0x%x ci_idepth %d\n",
   1158 	    xci_ilevel, xci_ipending, xci_idepth);
   1159 	printf("evtchn_upcall_pending %ld evtchn_upcall_mask %ld"
   1160 	    " evtchn_pending_sel 0x%lx\n",
   1161 		upcall_pending, upcall_mask, pending_sel);
   1162 	printf("evtchn_mask");
   1163 	for (i = 0 ; i <= LONG_MASK; i++)
   1164 		printf(" %lx", (u_long)evtchn_mask[i]);
   1165 	printf("\n");
   1166 	printf("evtchn_pending");
   1167 	for (i = 0 ; i <= LONG_MASK; i++)
   1168 		printf(" %lx", (u_long)evtchn_pending[i]);
   1169 	printf("\n");
   1170 	return 0;
   1171 }
   1172 
   1173 static struct evtsource *
   1174 event_get_handler(const char *intrid)
   1175 {
   1176 	for (int i = 0; i < NR_EVENT_CHANNELS; i++) {
   1177 		if (evtsource[i] == NULL || i == debug_port)
   1178 			continue;
   1179 
   1180 		struct evtsource *evp = evtsource[i];
   1181 
   1182 		if (strcmp(evp->ev_intrname, intrid) == 0)
   1183 			return evp;
   1184 	}
   1185 
   1186 	return NULL;
   1187 }
   1188 
   1189 static uint64_t
   1190 xen_intr_get_count(const char *intrid, u_int cpu_idx)
   1191 {
   1192 	int count = 0;
   1193 	struct evtsource *evp;
   1194 
   1195 	mutex_spin_enter(&evtchn_lock);
   1196 
   1197 	evp = event_get_handler(intrid);
   1198 	if (evp != NULL && cpu_idx == cpu_index(evp->ev_cpu))
   1199 		count = evp->ev_evcnt.ev_count;
   1200 
   1201 	mutex_spin_exit(&evtchn_lock);
   1202 
   1203 	return count;
   1204 }
   1205 
   1206 static void
   1207 xen_intr_get_assigned(const char *intrid, kcpuset_t *cpuset)
   1208 {
   1209 	struct evtsource *evp;
   1210 
   1211 	kcpuset_zero(cpuset);
   1212 
   1213 	mutex_spin_enter(&evtchn_lock);
   1214 
   1215 	evp = event_get_handler(intrid);
   1216 	if (evp != NULL)
   1217 		kcpuset_set(cpuset, cpu_index(evp->ev_cpu));
   1218 
   1219 	mutex_spin_exit(&evtchn_lock);
   1220 }
   1221 
   1222 static void
   1223 xen_intr_get_devname(const char *intrid, char *buf, size_t len)
   1224 {
   1225 	struct evtsource *evp;
   1226 
   1227 	mutex_spin_enter(&evtchn_lock);
   1228 
   1229 	evp = event_get_handler(intrid);
   1230 	strlcpy(buf, evp ? evp->ev_xname : "unknown", len);
   1231 
   1232 	mutex_spin_exit(&evtchn_lock);
   1233 }
   1234 
   1235 #ifdef XENPV
   1236 /*
   1237  * MI interface for subr_interrupt.
   1238  */
   1239 struct intrids_handler *
   1240 interrupt_construct_intrids(const kcpuset_t *cpuset)
   1241 {
   1242 	struct intrids_handler *ii_handler;
   1243 	intrid_t *ids;
   1244 	int i, count, off;
   1245 	struct evtsource *evp;
   1246 
   1247 	if (kcpuset_iszero(cpuset))
   1248 		return 0;
   1249 
   1250 	/*
   1251 	 * Count the number of interrupts which affinity to any cpu of "cpuset".
   1252 	 */
   1253 	count = 0;
   1254 	for (i = 0; i < NR_EVENT_CHANNELS; i++) {
   1255 		evp = evtsource[i];
   1256 
   1257 		if (evp == NULL || i == debug_port)
   1258 			continue;
   1259 
   1260 		if (!kcpuset_isset(cpuset, cpu_index(evp->ev_cpu)))
   1261 			continue;
   1262 
   1263 		count++;
   1264 	}
   1265 
   1266 	ii_handler = kmem_zalloc(sizeof(int) + sizeof(intrid_t) * count,
   1267 	    KM_SLEEP);
   1268 	if (ii_handler == NULL)
   1269 		return NULL;
   1270 	ii_handler->iih_nids = count;
   1271 	if (count == 0)
   1272 		return ii_handler;
   1273 
   1274 	ids = ii_handler->iih_intrids;
   1275 	mutex_spin_enter(&evtchn_lock);
   1276 	for (i = 0, off = 0; i < NR_EVENT_CHANNELS && off < count; i++) {
   1277 		evp = evtsource[i];
   1278 
   1279 		if (evp == NULL || i == debug_port)
   1280 			continue;
   1281 
   1282 		if (!kcpuset_isset(cpuset, cpu_index(evp->ev_cpu)))
   1283 			continue;
   1284 
   1285 		snprintf(ids[off], sizeof(intrid_t), "%s", evp->ev_intrname);
   1286 		off++;
   1287 	}
   1288 	mutex_spin_exit(&evtchn_lock);
   1289 	return ii_handler;
   1290 }
   1291 __strong_alias(interrupt_get_count, xen_intr_get_count);
   1292 __strong_alias(interrupt_get_assigned, xen_intr_get_assigned);
   1293 __strong_alias(interrupt_get_devname, xen_intr_get_devname);
   1294 __strong_alias(x86_intr_get_count, xen_intr_get_count);
   1295 __strong_alias(x86_intr_get_assigned, xen_intr_get_assigned);
   1296 __strong_alias(x86_intr_get_devname, xen_intr_get_devname);
   1297 #endif /* XENPV */
   1298