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