Index: sys/xen/xen_intr.c =================================================================== --- sys/xen/xen_intr.c +++ sys/xen/xen_intr.c @@ -268,7 +268,7 @@ * object or NULL. */ static struct xenisrc * -xen_intr_alloc_isrc(enum evtchn_type type) +xen_intr_alloc_isrc(enum evtchn_type type, evtchn_port_t port) { static int warned; struct xenisrc *isrc; @@ -279,7 +279,7 @@ if (isrc != NULL) { mtx_unlock(&xen_intr_x86_lock); - return (isrc); + goto out; } if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) { @@ -304,8 +304,23 @@ isrc->xi_type = type; if (intr_register_source(&isrc->xi_arch.xai_intsrc) != 0) { free(isrc, M_XENINTR); - isrc = NULL; + return (NULL); + } + +out: + /* xen_intr_assign_cpu() requires this to be set */ + isrc->xi_port = port; + +#ifdef SMP + if (type == EVTCHN_TYPE_PORT) { + /* + * By default all interrupts are assigned to vCPU#0 + * unless specified otherwise, so shuffle them to balance + * the interrupt load. + */ + xen_intr_assign_cpu(isrc, intr_next_cpu(0)); } +#endif return (isrc); } @@ -394,11 +409,10 @@ return (EINVAL); } - isrc = xen_intr_alloc_isrc(type); + isrc = xen_intr_alloc_isrc(type, local_port); if (isrc == NULL) return (ENOSPC); mtx_lock(&xen_intr_isrc_lock); - isrc->xi_port = local_port; xen_intr_port_to_isrc[isrc->xi_port] = isrc; refcount_init(&isrc->xi_refcount, 1); mtx_unlock(&xen_intr_isrc_lock); @@ -406,17 +420,6 @@ /* Assign the opaque handler */ *port_handlep = xen_intr_handle_from_isrc(isrc); -#ifdef SMP - if (type == EVTCHN_TYPE_PORT) { - /* - * By default all interrupts are assigned to vCPU#0 - * unless specified otherwise, so shuffle them to balance - * the interrupt load. - */ - xen_intr_assign_cpu(isrc, intr_next_cpu(0)); - } -#endif - if (filter == NULL && handler == NULL) { /* * No filter/handler provided, leave the event channel