Module Name:    src
Committed By:   cherry
Date:           Thu Aug 11 17:59:00 UTC 2011

Modified Files:
        src/sys/arch/xen/include: evtchn.h intr.h
        src/sys/arch/xen/x86: intr.c
        src/sys/arch/xen/xen: evtchn.c xenevt.c

Log Message:
Make event/interrupt handling MP aware


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/xen/include/evtchn.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/xen/include/intr.h
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/xen/x86/intr.c
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/xen/xen/evtchn.c
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/xen/xen/xenevt.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/xen/include/evtchn.h
diff -u src/sys/arch/xen/include/evtchn.h:1.18 src/sys/arch/xen/include/evtchn.h:1.19
--- src/sys/arch/xen/include/evtchn.h:1.18	Fri Oct 23 02:32:33 2009
+++ src/sys/arch/xen/include/evtchn.h	Thu Aug 11 17:58:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: evtchn.h,v 1.18 2009/10/23 02:32:33 snj Exp $	*/
+/*	$NetBSD: evtchn.h,v 1.19 2011/08/11 17:58:59 cherry Exp $	*/
 
 /*
  *
@@ -41,8 +41,9 @@
 int event_set_handler(int, int (*func)(void *), void *, int, const char *);
 int event_remove_handler(int, int (*func)(void *), void *);
 
+struct cpu_info;
 struct intrhand;
-void event_set_iplhandler(struct intrhand *, int);
+void event_set_iplhandler(struct cpu_info *, struct intrhand *, int);
 
 extern int debug_port;
 extern int xen_debug_handler(void *);
@@ -52,6 +53,8 @@
 int unbind_pirq_from_evtch(int);
 int unbind_virq_from_evtch(int);
 
+evtchn_port_t bind_vcpu_to_evtch(cpuid_t);
+
 struct pintrhand {
 	int pirq;
 	int evtch;

Index: src/sys/arch/xen/include/intr.h
diff -u src/sys/arch/xen/include/intr.h:1.32 src/sys/arch/xen/include/intr.h:1.33
--- src/sys/arch/xen/include/intr.h:1.32	Wed Aug 10 11:39:45 2011
+++ src/sys/arch/xen/include/intr.h	Thu Aug 11 17:58:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.h,v 1.32 2011/08/10 11:39:45 cherry Exp $	*/
+/*	$NetBSD: intr.h,v 1.33 2011/08/11 17:58:59 cherry Exp $	*/
 /*	NetBSD intr.h,v 1.15 2004/10/31 10:39:34 yamt Exp	*/
 
 /*-
@@ -54,6 +54,7 @@
 	uint32_t ev_imask;		/* interrupt mask */
 	struct intrhand *ev_handlers;	/* handler chain */
 	struct evcnt ev_evcnt;		/* interrupt counter */
+	struct cpu_info *ev_cpu;        /* cpu on which this event is bound */
 	char ev_evname[32];		/* event counter name */
 };
 
@@ -161,7 +162,6 @@
 
 void intr_default_setup(void);
 int x86_nmi(void);
-void intr_calculatemasks(struct evtsource *);
 
 void *intr_establish(int, struct pic *, int, int, int, int (*)(void *), void *, bool);
 void intr_disestablish(struct intrhand *);
@@ -180,9 +180,9 @@
 int xen_send_ipi(struct cpu_info *, uint32_t);
 void xen_broadcast_ipi(uint32_t);
 #else
-#define xen_ipi_init(_1) do {} while(0) /* nothing */
-#define xen_send_ipi(_i1, _i2) do {} while(0) /* nothing */
-#define xen_broadcast_ipi(_i1) do {} while(0) /* nothing */
+#define xen_ipi_init(_1) ((void) 0) /* nothing */
+#define xen_send_ipi(_i1, _i2) (0) /* nothing */
+#define xen_broadcast_ipi(_i1) ((void) 0) /* nothing */
 #endif /* MULTIPROCESSOR */
 
 #endif /* !_LOCORE */

Index: src/sys/arch/xen/x86/intr.c
diff -u src/sys/arch/xen/x86/intr.c:1.27 src/sys/arch/xen/x86/intr.c:1.28
--- src/sys/arch/xen/x86/intr.c:1.27	Fri Mar 19 23:27:12 2010
+++ src/sys/arch/xen/x86/intr.c	Thu Aug 11 17:59:00 2011
@@ -103,7 +103,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.27 2010/03/19 23:27:12 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.28 2011/08/11 17:59:00 cherry Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_xen.h"
@@ -119,6 +119,7 @@
 #include <sys/proc.h>
 #include <sys/errno.h>
 #include <sys/cpu.h>
+#include <sys/simplelock.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -153,24 +154,6 @@
 #endif
 
 /*
- * Recalculate the interrupt from scratch for an event source.
- */
-void
-intr_calculatemasks(struct evtsource *evts)
-{
-	struct intrhand *ih;
-
-	evts->ev_maxlevel = IPL_NONE;
-	evts->ev_imask = 0;
-	for (ih = evts->ev_handlers; ih != NULL; ih = ih->ih_evt_next) {
-		if (ih->ih_level > evts->ev_maxlevel)
-			evts->ev_maxlevel = ih->ih_level;
-		evts->ev_imask |= (1 << ih->ih_level);
-	}
-
-}
-
-/*
  * Fake interrupt handler structures for the benefit of symmetry with
  * other interrupt sources.
  */

Index: src/sys/arch/xen/xen/evtchn.c
diff -u src/sys/arch/xen/xen/evtchn.c:1.49 src/sys/arch/xen/xen/evtchn.c:1.50
--- src/sys/arch/xen/xen/evtchn.c:1.49	Wed Aug 10 21:46:02 2011
+++ src/sys/arch/xen/xen/evtchn.c	Thu Aug 11 17:59:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: evtchn.c,v 1.49 2011/08/10 21:46:02 cherry Exp $	*/
+/*	$NetBSD: evtchn.c,v 1.50 2011/08/11 17:59:00 cherry Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -54,20 +54,21 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.49 2011/08/10 21:46:02 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.50 2011/08/11 17:59:00 cherry Exp $");
 
 #include "opt_xen.h"
 #include "isa.h"
 #include "pci.h"
 
 #include <sys/param.h>
+#include <sys/cpu.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/proc.h>
 #include <sys/malloc.h>
 #include <sys/reboot.h>
-#include <sys/simplelock.h>
+#include <sys/mutex.h>
 
 #include <uvm/uvm.h>
 
@@ -82,14 +83,23 @@
  * This lock protects updates to the following mapping and reference-count
  * arrays. The lock does not need to be acquired to read the mapping tables.
  */
-static struct simplelock irq_mapping_update_lock = SIMPLELOCK_INITIALIZER;
+static kmutex_t evtchn_lock;
 
 /* event handlers */
 struct evtsource *evtsource[NR_EVENT_CHANNELS];
 
-/* Reference counts for bindings to event channels */
+/* channel locks */
+static kmutex_t evtlock[NR_EVENT_CHANNELS];
+
+/* Reference counts for bindings to event channels XXX: redo for SMP */
 static uint8_t evtch_bindcount[NR_EVENT_CHANNELS];
 
+/* event-channel <-> VCPU mapping for IPIs. XXX: redo for SMP. */
+static evtchn_port_t vcpu_ipi_to_evtch[MAX_VIRT_CPUS];
+
+/* event-channel <-> VCPU mapping for VIRQ_TIMER.  XXX: redo for SMP. */
+static int virq_timer_to_evtch[MAX_VIRT_CPUS];
+
 /* event-channel <-> VIRQ mapping. */
 static int virq_to_evtch[NR_VIRQS];
 
@@ -137,6 +147,14 @@
 {
 	int i;
 
+	/* No VCPU -> event mappings. */
+	for (i = 0; i < MAX_VIRT_CPUS; i++)
+		vcpu_ipi_to_evtch[i] = -1;
+
+	/* No VIRQ_TIMER -> event mappings. */
+	for (i = 0; i < MAX_VIRT_CPUS; i++)
+		virq_timer_to_evtch[i] = -1;
+
 	/* No VIRQ -> event mappings. */
 	for (i = 0; i < NR_VIRQS; i++)
 		virq_to_evtch[i] = -1;
@@ -162,6 +180,8 @@
 events_init(void)
 {
 	debug_port = bind_virq_to_evtch(VIRQ_DEBUG);
+	KASSERT(debug_port != -1);
+
 	aprint_verbose("debug virtual interrupt using event channel %d\n",
 	    debug_port);
 	/*
@@ -197,7 +217,7 @@
 	if (evtch == IRQ_DEBUG)
 		printf("evtchn_do_event: evtch %d\n", evtch);
 #endif
-	ci = &cpu_info_primary;
+	ci = curcpu();
 
 	/*
 	 * Shortcut for the debug handler, we want it to always run,
@@ -217,31 +237,46 @@
 	ci->ci_data.cpu_nintr++;
 	evtsource[evtch]->ev_evcnt.ev_count++;
 	ilevel = ci->ci_ilevel;
-	if (evtsource[evtch]->ev_maxlevel <= ilevel) {
+	if (evtsource[evtch]->ev_maxlevel <= ilevel ||
+	    evtsource[evtch]->ev_cpu != ci /* XXX: get stats */) {
 #ifdef IRQ_DEBUG
 		if (evtch == IRQ_DEBUG)
 		    printf("evtsource[%d]->ev_maxlevel %d <= ilevel %d\n",
 		    evtch, evtsource[evtch]->ev_maxlevel, ilevel);
 #endif
-		hypervisor_set_ipending(ci, evtsource[evtch]->ev_imask,
-		    evtch >> LONG_SHIFT, evtch & LONG_MASK);
-		/* leave masked */
+		hypervisor_set_ipending(evtsource[evtch]->ev_cpu,
+					evtsource[evtch]->ev_imask,
+					evtch >> LONG_SHIFT,
+					evtch & LONG_MASK);
+
+		if (evtsource[evtch]->ev_cpu != ci) { 
+			/* facilitate spllower() on remote cpu */
+			struct cpu_info *rci = evtsource[evtch]->ev_cpu;
+			if (xen_send_ipi(rci, XEN_IPI_KICK) != 0) {
+				panic("xen_send_ipi(%s, XEN_IPI_KICK) failed\n", cpu_name(rci));
+			}
+		}
+
+		/* leave masked */				     
 		return 0;
 	}
 	ci->ci_ilevel = evtsource[evtch]->ev_maxlevel;
 	iplmask = evtsource[evtch]->ev_imask;
 	sti();
+	mutex_spin_enter(&evtlock[evtch]);
 	ih = evtsource[evtch]->ev_handlers;
 	while (ih != NULL) {
-		if (ih->ih_level <= ilevel) {
+		if (ih->ih_level <= ilevel ||
+		   ih->ih_cpu != ci) {
 #ifdef IRQ_DEBUG
 		if (evtch == IRQ_DEBUG)
 		    printf("ih->ih_level %d <= ilevel %d\n", ih->ih_level, ilevel);
 #endif
 			cli();
-			hypervisor_set_ipending(ci, iplmask,
+			hypervisor_set_ipending(ih->ih_cpu, iplmask,
 			    evtch >> LONG_SHIFT, evtch & LONG_MASK);
 			/* leave masked */
+			mutex_spin_exit(&evtlock[evtch]);
 			goto splx;
 		}
 		iplmask &= ~IUNMASK(ci, ih->ih_level);
@@ -250,6 +285,7 @@
 		ih_fun(ih->ih_arg, regs);
 		ih = ih->ih_evt_next;
 	}
+	mutex_spin_exit(&evtlock[evtch]);
 	cli();
 	hypervisor_enable_event(evtch);
 splx:
@@ -267,6 +303,7 @@
 				ci->ci_ilevel = i;
 				for (ih = ci->ci_isources[i]->ipl_handlers;
 				    ih != NULL; ih = ih->ih_ipl_next) {
+					KASSERT(ih->ih_cpu == ci);
 					sti();
 					ih_fun = (void *)ih->ih_fun;
 					ih_fun(ih->ih_arg, regs);
@@ -292,6 +329,37 @@
 	return 0;
 }
 
+#define PRIuCPUID	"lu" /* XXX: move this somewhere more appropriate */
+
+evtchn_port_t
+bind_vcpu_to_evtch(cpuid_t vcpu)
+{
+	evtchn_op_t op;
+	evtchn_port_t evtchn;
+	int s;
+
+	s = splhigh();
+	mutex_spin_enter(&evtchn_lock);
+
+	evtchn = vcpu_ipi_to_evtch[vcpu];
+	if (evtchn == -1) {
+		op.cmd = EVTCHNOP_bind_ipi;
+		op.u.bind_ipi.vcpu = (uint32_t) vcpu;
+		if (HYPERVISOR_event_channel_op(&op) != 0)
+			panic("Failed to bind ipi to VCPU %"PRIuCPUID"\n", vcpu);
+		evtchn = op.u.bind_ipi.port;
+
+		vcpu_ipi_to_evtch[vcpu] = evtchn;
+	}
+
+	evtch_bindcount[evtchn]++;
+
+	mutex_spin_exit(&evtchn_lock);
+	splx(s);
+    
+	return evtchn;
+}
+
 int
 bind_virq_to_evtch(int virq)
 {
@@ -299,13 +367,31 @@
 	int evtchn, s;
 
 	s = splhigh();
-	simple_lock(&irq_mapping_update_lock);
+	mutex_spin_enter(&evtchn_lock);
+
+	/* 
+	 * XXX: The only per-cpu VIRQ we currently use is VIRQ_TIMER. 
+	 * Please re-visit this implementation when others are used. 
+	 * Note: VIRQ_DEBUG is special-cased, and not used or bound on APs.
+	 * XXX: event->virq/ipi can be unified in a linked-list
+	 * implementation.
+	 */
+	struct cpu_info *ci = curcpu();
+
+	if (virq == VIRQ_DEBUG && ci != &cpu_info_primary) {
+		return -1;
+	}
 
-	evtchn = virq_to_evtch[virq];
+	if (virq == VIRQ_TIMER) {
+		evtchn = virq_timer_to_evtch[ci->ci_cpuid];
+	}
+	else {
+		evtchn = virq_to_evtch[virq];
+	}
 	if (evtchn == -1) {
 		op.cmd = EVTCHNOP_bind_virq;
 		op.u.bind_virq.virq = virq;
-		op.u.bind_virq.vcpu = 0;
+		op.u.bind_virq.vcpu = ci->ci_cpuid;
 		if (HYPERVISOR_event_channel_op(&op) != 0)
 			panic("Failed to bind virtual IRQ %d\n", virq);
 		evtchn = op.u.bind_virq.port;
@@ -315,7 +401,7 @@
 
 	evtch_bindcount[evtchn]++;
 
-	simple_unlock(&irq_mapping_update_lock);
+	mutex_spin_exit(&evtchn_lock);
 	splx(s);
     
 	return evtchn;
@@ -325,10 +411,24 @@
 unbind_virq_from_evtch(int virq)
 {
 	evtchn_op_t op;
-	int evtchn = virq_to_evtch[virq];
-	int s = splhigh();
+	int evtchn;
+	int s;
+
+	struct cpu_info *ci = curcpu();
+
+	if (virq == VIRQ_TIMER) {
+		evtchn = virq_timer_to_evtch[ci->ci_cpuid];
+	}
+	else {
+		evtchn = virq_to_evtch[virq];
+	}
+
+	if (evtchn == -1) {
+		return -1;
+	}
 
-	simple_lock(&irq_mapping_update_lock);
+	s = splhigh();
+	mutex_spin_enter(&evtchn_lock);
 
 	evtch_bindcount[evtchn]--;
 	if (evtch_bindcount[evtchn] == 0) {
@@ -340,7 +440,7 @@
 		virq_to_evtch[virq] = -1;
 	}
 
-	simple_unlock(&irq_mapping_update_lock);
+	mutex_spin_exit(&evtchn_lock);
 	splx(s);
 
 	return evtchn;
@@ -358,7 +458,7 @@
 	}
 
 	s = splhigh();
-	simple_lock(&irq_mapping_update_lock);
+	mutex_spin_enter(&evtchn_lock);
 
 	evtchn = pirq_to_evtch[pirq];
 	if (evtchn == -1) {
@@ -377,7 +477,7 @@
 
 	evtch_bindcount[evtchn]++;
 
-	simple_unlock(&irq_mapping_update_lock);
+	mutex_spin_exit(&evtchn_lock);
 	splx(s);
     
 	return evtchn;
@@ -390,7 +490,7 @@
 	int evtchn = pirq_to_evtch[pirq];
 	int s = splhigh();
 
-	simple_lock(&irq_mapping_update_lock);
+	mutex_spin_enter(&evtchn_lock);
 
 	evtch_bindcount[evtchn]--;
 	if (evtch_bindcount[evtchn] == 0) {
@@ -402,7 +502,7 @@
 		pirq_to_evtch[pirq] = -1;
 	}
 
-	simple_unlock(&irq_mapping_update_lock);
+	mutex_spin_exit(&evtchn_lock);
 	splx(s);
 
 	return evtchn;
@@ -420,8 +520,10 @@
 		printf("pirq_establish: can't malloc handler info\n");
 		return NULL;
 	}
-
-	event_set_handler(evtch, pirq_interrupt, ih, level, evname);
+	if (event_set_handler(evtch, pirq_interrupt, ih, level, evname) != 0) {
+		free(ih, M_DEVBUF);
+		return NULL;
+	}
 	ih->pirq = pirq;
 	ih->evtch = evtch;
 	ih->func = func;
@@ -459,11 +561,34 @@
 
 #endif /* NPCI > 0 || NISA > 0 */
 
+
+/*
+ * Recalculate the interrupt from scratch for an event source.
+ */
+static void
+intr_calculatemasks(struct evtsource *evts, int evtch)
+{
+	struct intrhand *ih;
+
+#ifdef MULTIPROCESSOR
+	KASSERT(!mutex_owned(&evtlock[evtch]));
+#endif
+	mutex_spin_enter(&evtlock[evtch]);
+	evts->ev_maxlevel = IPL_NONE;
+	evts->ev_imask = 0;
+	for (ih = evts->ev_handlers; ih != NULL; ih = ih->ih_evt_next) {
+		if (ih->ih_level > evts->ev_maxlevel)
+			evts->ev_maxlevel = ih->ih_level;
+		evts->ev_imask |= (1 << ih->ih_level);
+	}
+	mutex_spin_exit(&evtlock[evtch]);
+}
+
 int
 event_set_handler(int evtch, int (*func)(void *), void *arg, int level,
     const char *evname)
 {
-	struct cpu_info *ci = &cpu_info_primary;
+	struct cpu_info *ci = curcpu(); /* XXX: pass in ci ? */
 	struct evtsource *evts;
 	struct intrhand *ih, **ihp;
 	int s;
@@ -497,6 +622,7 @@
 	ih->ih_arg = ih->ih_realarg = arg;
 	ih->ih_evt_next = NULL;
 	ih->ih_ipl_next = NULL;
+	ih->ih_cpu = ci;
 #ifdef MULTIPROCESSOR
 	if (!mpsafe) {
 		ih->ih_fun = intr_biglock_wrapper;
@@ -506,8 +632,8 @@
 
 	s = splhigh();
 
-	/* register handler for spllower() */
-	event_set_iplhandler(ih, level);
+	/* register per-cpu handler for spllower() */
+	event_set_iplhandler(ci, ih, level);
 
 	/* register handler for event channel */
 	if (evtsource[evtch] == NULL) {
@@ -515,7 +641,16 @@
 		    M_DEVBUF, M_WAITOK|M_ZERO);
 		if (evts == NULL)
 			panic("can't allocate fixed interrupt source");
+
 		evts->ev_handlers = ih;
+		/* 
+		 * XXX: We're assuming here that ci is the same cpu as
+		 * the one on which this event/port is bound on. The
+		 * api needs to be reshuffled so that this assumption
+		 * is more explicitly implemented.
+		 */
+		evts->ev_cpu = ci; 
+		mutex_init(&evtlock[evtch], MUTEX_DEFAULT, IPL_VM);
 		evtsource[evtch] = evts;
 		if (evname)
 			strncpy(evts->ev_evname, evname,
@@ -528,6 +663,7 @@
 	} else {
 		evts = evtsource[evtch];
 		/* sort by IPL order, higher first */
+		mutex_spin_enter(&evtlock[evtch]);
 		for (ihp = &evts->ev_handlers; ; ihp = &((*ihp)->ih_evt_next)) {
 			if ((*ihp)->ih_level < ih->ih_level) {
 				/* insert before *ihp */
@@ -540,20 +676,23 @@
 				break;
 			}
 		}
+		mutex_spin_exit(&evtlock[evtch]);
 	}
 
-	intr_calculatemasks(evts);
+	intr_calculatemasks(evts, evtch);
 	splx(s);
 
 	return 0;
 }
 
 void
-event_set_iplhandler(struct intrhand *ih, int level)
+event_set_iplhandler(struct cpu_info *ci,
+		     struct intrhand *ih,
+		     int level)
 {
-	struct cpu_info *ci = &cpu_info_primary;
 	struct iplsource *ipls;
 
+	KASSERT(ci == ih->ih_cpu);
 	if (ci->ci_isources[level] == NULL) {
 		ipls = malloc(sizeof (struct iplsource),
 		    M_DEVBUF, M_WAITOK|M_ZERO);
@@ -577,21 +716,25 @@
 	struct evtsource *evts;
 	struct intrhand *ih;
 	struct intrhand **ihp;
-	struct cpu_info *ci = &cpu_info_primary;
+	struct cpu_info *ci = curcpu();
 
 	evts = evtsource[evtch];
 	if (evts == NULL)
 		return ENOENT;
 
+	mutex_spin_enter(&evtlock[evtch]);
 	for (ihp = &evts->ev_handlers, ih = evts->ev_handlers;
 	    ih != NULL;
 	    ihp = &ih->ih_evt_next, ih = ih->ih_evt_next) {
 		if (ih->ih_fun == func && ih->ih_arg == arg)
 			break;
 	}
-	if (ih == NULL)
+	if (ih == NULL) {
+		mutex_spin_exit(&evtlock[evtch]);
 		return ENOENT;
+	}
 	*ihp = ih->ih_evt_next;
+	mutex_spin_exit(&evtlock[evtch]);
 
 	ipls = ci->ci_isources[ih->ih_level];
 	for (ihp = &ipls->ipl_handlers, ih = ipls->ipl_handlers;
@@ -609,7 +752,7 @@
 		free(evts, M_DEVBUF);
 		evtsource[evtch] = NULL;
 	} else {
-		intr_calculatemasks(evts);
+		intr_calculatemasks(evts, evtch);
 	}
 	return 0;
 }

Index: src/sys/arch/xen/xen/xenevt.c
diff -u src/sys/arch/xen/xen/xenevt.c:1.37 src/sys/arch/xen/xen/xenevt.c:1.38
--- src/sys/arch/xen/xen/xenevt.c:1.37	Sun May 22 04:27:15 2011
+++ src/sys/arch/xen/xen/xenevt.c	Thu Aug 11 17:59:00 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: xenevt.c,v 1.37 2011/05/22 04:27:15 rmind Exp $      */
+/*      $NetBSD: xenevt.c,v 1.38 2011/08/11 17:59:00 cherry Exp $      */
 
 /*
  * Copyright (c) 2005 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.37 2011/05/22 04:27:15 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.38 2011/08/11 17:59:00 cherry Exp $");
 
 #include "opt_xen.h"
 #include <sys/param.h>
@@ -160,6 +160,7 @@
 	ih->ih_fun = ih->ih_realfun = xenevt_processevt;
 	ih->ih_arg = ih->ih_realarg = NULL;
 	ih->ih_ipl_next = NULL;
+	ih->ih_cpu = curcpu();
 #ifdef MULTIPROCESSOR
 	if (!mpsafe) {
 		ih->ih_fun = intr_biglock_wrapper;
@@ -168,7 +169,7 @@
 #endif /* MULTIPROCESSOR */
 
 	s = splhigh();
-	event_set_iplhandler(ih, level);
+	event_set_iplhandler(ih->ih_cpu, ih, level);
 	splx(s);
 }
 
@@ -178,7 +179,7 @@
 {
 	xenevt_ev1 |= 1UL << l1;
 	xenevt_ev2[l1] |= 1UL << l2;
-	curcpu()->ci_ipending |= 1 << IPL_HIGH;
+	curcpu()/*XXX*/->ci_ipending |= 1 << IPL_HIGH;
 }
 
 /* process pending events */

Reply via email to