Tue Apr 14 14:59:11 2015 UTC ()
Pull up following revision(s) (requested by bouyer in ticket #1278):
	sys/arch/xen/include/evtchn.h: revision 1.23
	sys/arch/xen/xen/evtchn.c: revision 1.71
	sys/arch/xen/xen/pci_intr_machdep.c: revision 1.17
Properly implemement pci_intr_disestablish(9), so that interrupt
handlers stop being called when the device has been detached.
Should fix PR port-xen/47720 (which turns out to not be related to raidframe).
While there fix possible races in event_remove_handler() and pirq_establish().


(msaitoh)
diff -r1.20 -r1.20.8.1 src/sys/arch/xen/include/evtchn.h
diff -r1.62.2.1 -r1.62.2.2 src/sys/arch/xen/xen/evtchn.c
diff -r1.15 -r1.15.8.1 src/sys/arch/xen/xen/pci_intr_machdep.c

cvs diff -r1.20 -r1.20.8.1 src/sys/arch/xen/include/evtchn.h (expand / switch to unified diff)

--- src/sys/arch/xen/include/evtchn.h 2011/09/20 00:12:23 1.20
+++ src/sys/arch/xen/include/evtchn.h 2015/04/14 14:59:11 1.20.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: evtchn.h,v 1.20 2011/09/20 00:12:23 jym Exp $ */ 1/* $NetBSD: evtchn.h,v 1.20.8.1 2015/04/14 14:59:11 msaitoh Exp $ */
2 2
3/* 3/*
4 * 4 *
5 * Copyright (c) 2004 Christian Limpach. 5 * Copyright (c) 2004 Christian Limpach.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -57,15 +57,16 @@ int unbind_pirq_from_evtch(int); @@ -57,15 +57,16 @@ int unbind_pirq_from_evtch(int);
57int unbind_virq_from_evtch(int); 57int unbind_virq_from_evtch(int);
58 58
59evtchn_port_t bind_vcpu_to_evtch(cpuid_t); 59evtchn_port_t bind_vcpu_to_evtch(cpuid_t);
60 60
61struct pintrhand { 61struct pintrhand {
62 int pirq; 62 int pirq;
63 int evtch; 63 int evtch;
64 int (*func)(void *); 64 int (*func)(void *);
65 void *arg; 65 void *arg;
66}; 66};
67 67
68struct pintrhand *pirq_establish(int, int, int (*)(void *), void *, int, 68struct pintrhand *pirq_establish(int, int, int (*)(void *), void *, int,
69 const char *); 69 const char *);
 70void pirq_disestablish(struct pintrhand *);
70 71
71#endif /* _XEN_EVENTS_H_ */ 72#endif /* _XEN_EVENTS_H_ */

cvs diff -r1.62.2.1 -r1.62.2.2 src/sys/arch/xen/xen/evtchn.c (expand / switch to unified diff)

--- src/sys/arch/xen/xen/evtchn.c 2013/12/17 22:39:17 1.62.2.1
+++ src/sys/arch/xen/xen/evtchn.c 2015/04/14 14:59:11 1.62.2.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: evtchn.c,v 1.62.2.1 2013/12/17 22:39:17 riz Exp $ */ 1/* $NetBSD: evtchn.c,v 1.62.2.2 2015/04/14 14:59:11 msaitoh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Manuel Bouyer. 4 * Copyright (c) 2006 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -44,27 +44,27 @@ @@ -44,27 +44,27 @@
44 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 44 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 46 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 52 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 */ 53 */
54 54
55 55
56#include <sys/cdefs.h> 56#include <sys/cdefs.h>
57__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.62.2.1 2013/12/17 22:39:17 riz Exp $"); 57__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.62.2.2 2015/04/14 14:59:11 msaitoh Exp $");
58 58
59#include "opt_xen.h" 59#include "opt_xen.h"
60#include "isa.h" 60#include "isa.h"
61#include "pci.h" 61#include "pci.h"
62 62
63#include <sys/param.h> 63#include <sys/param.h>
64#include <sys/cpu.h> 64#include <sys/cpu.h>
65#include <sys/kernel.h> 65#include <sys/kernel.h>
66#include <sys/systm.h> 66#include <sys/systm.h>
67#include <sys/device.h> 67#include <sys/device.h>
68#include <sys/proc.h> 68#include <sys/proc.h>
69#include <sys/kmem.h> 69#include <sys/kmem.h>
70#include <sys/reboot.h> 70#include <sys/reboot.h>
@@ -544,51 +544,62 @@ struct pintrhand * @@ -544,51 +544,62 @@ struct pintrhand *
544pirq_establish(int pirq, int evtch, int (*func)(void *), void *arg, int level, 544pirq_establish(int pirq, int evtch, int (*func)(void *), void *arg, int level,
545 const char *evname) 545 const char *evname)
546{ 546{
547 struct pintrhand *ih; 547 struct pintrhand *ih;
548 physdev_op_t physdev_op; 548 physdev_op_t physdev_op;
549 549
550 ih = kmem_zalloc(sizeof(struct pintrhand), 550 ih = kmem_zalloc(sizeof(struct pintrhand),
551 cold ? KM_NOSLEEP : KM_SLEEP); 551 cold ? KM_NOSLEEP : KM_SLEEP);
552 if (ih == NULL) { 552 if (ih == NULL) {
553 printf("pirq_establish: can't allocate handler info\n"); 553 printf("pirq_establish: can't allocate handler info\n");
554 return NULL; 554 return NULL;
555 } 555 }
556 556
557 if (event_set_handler(evtch, pirq_interrupt, ih, level, evname) != 0) { 
558 kmem_free(ih, sizeof(struct pintrhand)); 
559 return NULL; 
560 } 
561 
562 ih->pirq = pirq; 557 ih->pirq = pirq;
563 ih->evtch = evtch; 558 ih->evtch = evtch;
564 ih->func = func; 559 ih->func = func;
565 ih->arg = arg; 560 ih->arg = arg;
566 561
 562 if (event_set_handler(evtch, pirq_interrupt, ih, level, evname) != 0) {
 563 kmem_free(ih, sizeof(struct pintrhand));
 564 return NULL;
 565 }
 566
567 physdev_op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY; 567 physdev_op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
568 physdev_op.u.irq_status_query.irq = pirq; 568 physdev_op.u.irq_status_query.irq = pirq;
569 if (HYPERVISOR_physdev_op(&physdev_op) < 0) 569 if (HYPERVISOR_physdev_op(&physdev_op) < 0)
570 panic("HYPERVISOR_physdev_op(PHYSDEVOP_IRQ_STATUS_QUERY)"); 570 panic("HYPERVISOR_physdev_op(PHYSDEVOP_IRQ_STATUS_QUERY)");
571 if (physdev_op.u.irq_status_query.flags & 571 if (physdev_op.u.irq_status_query.flags &
572 PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY) { 572 PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY) {
573 pirq_needs_unmask_notify[evtch >> 5] |= (1 << (evtch & 0x1f)); 573 pirq_needs_unmask_notify[evtch >> 5] |= (1 << (evtch & 0x1f));
574#ifdef IRQ_DEBUG 574#ifdef IRQ_DEBUG
575 printf("pirq %d needs notify\n", pirq); 575 printf("pirq %d needs notify\n", pirq);
576#endif 576#endif
577 } 577 }
578 hypervisor_enable_event(evtch); 578 hypervisor_enable_event(evtch);
579 return ih; 579 return ih;
580} 580}
581 581
 582void
 583pirq_disestablish(struct pintrhand *ih)
 584{
 585 int error = event_remove_handler(ih->evtch, pirq_interrupt, ih);
 586 if (error) {
 587 printf("pirq_disestablish(%p): %d\n", ih, error);
 588 return;
 589 }
 590 kmem_free(ih, sizeof(struct pintrhand));
 591}
 592
582int 593int
583pirq_interrupt(void *arg) 594pirq_interrupt(void *arg)
584{ 595{
585 struct pintrhand *ih = arg; 596 struct pintrhand *ih = arg;
586 int ret; 597 int ret;
587 598
588 599
589 ret = ih->func(ih->arg); 600 ret = ih->func(ih->arg);
590#ifdef IRQ_DEBUG 601#ifdef IRQ_DEBUG
591 if (ih->evtch == IRQ_DEBUG) 602 if (ih->evtch == IRQ_DEBUG)
592 printf("pirq_interrupt irq %d ret %d\n", ih->pirq, ret); 603 printf("pirq_interrupt irq %d ret %d\n", ih->pirq, ret);
593#endif 604#endif
594 return ret; 605 return ret;
@@ -766,38 +777,38 @@ event_remove_handler(int evtch, int (*fu @@ -766,38 +777,38 @@ event_remove_handler(int evtch, int (*fu
766 mutex_spin_enter(&evtlock[evtch]); 777 mutex_spin_enter(&evtlock[evtch]);
767 for (ihp = &evts->ev_handlers, ih = evts->ev_handlers; 778 for (ihp = &evts->ev_handlers, ih = evts->ev_handlers;
768 ih != NULL; 779 ih != NULL;
769 ihp = &ih->ih_evt_next, ih = ih->ih_evt_next) { 780 ihp = &ih->ih_evt_next, ih = ih->ih_evt_next) {
770 if (ih->ih_realfun == func && ih->ih_realarg == arg) 781 if (ih->ih_realfun == func && ih->ih_realarg == arg)
771 break; 782 break;
772 } 783 }
773 if (ih == NULL) { 784 if (ih == NULL) {
774 mutex_spin_exit(&evtlock[evtch]); 785 mutex_spin_exit(&evtlock[evtch]);
775 return ENOENT; 786 return ENOENT;
776 } 787 }
777 ci = ih->ih_cpu; 788 ci = ih->ih_cpu;
778 *ihp = ih->ih_evt_next; 789 *ihp = ih->ih_evt_next;
779 mutex_spin_exit(&evtlock[evtch]); 
780 790
781 ipls = ci->ci_isources[ih->ih_level]; 791 ipls = ci->ci_isources[ih->ih_level];
782 for (ihp = &ipls->ipl_handlers, ih = ipls->ipl_handlers; 792 for (ihp = &ipls->ipl_handlers, ih = ipls->ipl_handlers;
783 ih != NULL; 793 ih != NULL;
784 ihp = &ih->ih_ipl_next, ih = ih->ih_ipl_next) { 794 ihp = &ih->ih_ipl_next, ih = ih->ih_ipl_next) {
785 if (ih->ih_realfun == func && ih->ih_realarg == arg) 795 if (ih->ih_realfun == func && ih->ih_realarg == arg)
786 break; 796 break;
787 } 797 }
788 if (ih == NULL) 798 if (ih == NULL)
789 panic("event_remove_handler"); 799 panic("event_remove_handler");
790 *ihp = ih->ih_ipl_next; 800 *ihp = ih->ih_ipl_next;
 801 mutex_spin_exit(&evtlock[evtch]);
791 kmem_free(ih, sizeof (struct intrhand)); 802 kmem_free(ih, sizeof (struct intrhand));
792 if (evts->ev_handlers == NULL) { 803 if (evts->ev_handlers == NULL) {
793 xen_atomic_clear_bit(&ci->ci_evtmask[0], evtch); 804 xen_atomic_clear_bit(&ci->ci_evtmask[0], evtch);
794 evcnt_detach(&evts->ev_evcnt); 805 evcnt_detach(&evts->ev_evcnt);
795 kmem_free(evts, sizeof (struct evtsource)); 806 kmem_free(evts, sizeof (struct evtsource));
796 evtsource[evtch] = NULL; 807 evtsource[evtch] = NULL;
797 } else { 808 } else {
798 intr_calculatemasks(evts, evtch, ci); 809 intr_calculatemasks(evts, evtch, ci);
799 } 810 }
800 return 0; 811 return 0;
801} 812}
802 813
803void 814void

cvs diff -r1.15 -r1.15.8.1 src/sys/arch/xen/xen/Attic/pci_intr_machdep.c (expand / switch to unified diff)

--- src/sys/arch/xen/xen/Attic/pci_intr_machdep.c 2011/07/01 18:36:45 1.15
+++ src/sys/arch/xen/xen/Attic/pci_intr_machdep.c 2015/04/14 14:59:11 1.15.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pci_intr_machdep.c,v 1.15 2011/07/01 18:36:45 dyoung Exp $ */ 1/* $NetBSD: pci_intr_machdep.c,v 1.15.8.1 2015/04/14 14:59:11 msaitoh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Manuel Bouyer. 4 * Copyright (c) 2005 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -16,27 +16,27 @@ @@ -16,27 +16,27 @@
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * 25 *
26 */ 26 */
27 27
28#include <sys/cdefs.h> 28#include <sys/cdefs.h>
29__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.15 2011/07/01 18:36:45 dyoung Exp $"); 29__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.15.8.1 2015/04/14 14:59:11 msaitoh Exp $");
30 30
31#include <sys/types.h> 31#include <sys/types.h>
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/systm.h> 33#include <sys/systm.h>
34 34
35#include <sys/bus.h> 35#include <sys/bus.h>
36#include <machine/bus_private.h> 36#include <machine/bus_private.h>
37 37
38#include <dev/pci/pcivar.h> 38#include <dev/pci/pcivar.h>
39#include <dev/pci/pcidevs.h> 39#include <dev/pci/pcidevs.h>
40 40
41#include <xen/evtchn.h> 41#include <xen/evtchn.h>
42 42
@@ -211,14 +211,15 @@ pci_intr_establish(pci_chipset_tag_t pci @@ -211,14 +211,15 @@ pci_intr_establish(pci_chipset_tag_t pci
211 snprintf(evname, sizeof(evname), "%s pin %d", 211 snprintf(evname, sizeof(evname), "%s pin %d",
212 device_xname(pic->sc_dev), APIC_IRQ_PIN(intrh.pirq)); 212 device_xname(pic->sc_dev), APIC_IRQ_PIN(intrh.pirq));
213 } else 213 } else
214#endif 214#endif
215 snprintf(evname, sizeof(evname), "irq%d", intrh.pirq); 215 snprintf(evname, sizeof(evname), "irq%d", intrh.pirq);
216 216
217 return (void *)pirq_establish(intrh.pirq & 0xff, 217 return (void *)pirq_establish(intrh.pirq & 0xff,
218 intrh.evtch, func, arg, level, evname); 218 intrh.evtch, func, arg, level, evname);
219} 219}
220 220
221void 221void
222pci_intr_disestablish(pci_chipset_tag_t pcitag, void *cookie) 222pci_intr_disestablish(pci_chipset_tag_t pcitag, void *cookie)
223{ 223{
 224 pirq_disestablish(cookie);
224} 225}