Changeset View
Changeset View
Standalone View
Standalone View
sys/xen/xen_intr.c
Show First 20 Lines • Show All 696 Lines • ▼ Show 20 Lines | |||||
xen_rebind_ipi(struct xenisrc *isrc) | xen_rebind_ipi(struct xenisrc *isrc) | ||||
{ | { | ||||
#ifdef SMP | #ifdef SMP | ||||
int cpu = isrc->xi_cpu; | int cpu = isrc->xi_cpu; | ||||
int vcpu_id = PCPU_ID_GET(cpu); | int vcpu_id = PCPU_ID_GET(cpu); | ||||
int error; | int error; | ||||
struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id }; | struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id }; | ||||
mtx_assert(&xen_intr_isrc_lock, MA_OWNED); | |||||
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, | error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, | ||||
&bind_ipi); | &bind_ipi); | ||||
if (error != 0) | if (error != 0) | ||||
panic("unable to rebind xen IPI: %d", error); | panic("unable to rebind xen IPI: %d", error); | ||||
isrc->xi_port = bind_ipi.port; | isrc->xi_port = bind_ipi.port; | ||||
#else | #else | ||||
panic("Resume IPI event channel on UP"); | panic("Resume IPI event channel on UP"); | ||||
#endif | #endif | ||||
} | } | ||||
static void | static void | ||||
xen_rebind_virq(struct xenisrc *isrc) | xen_rebind_virq(struct xenisrc *isrc) | ||||
{ | { | ||||
int cpu = isrc->xi_cpu; | int cpu = isrc->xi_cpu; | ||||
int vcpu_id = PCPU_ID_GET(cpu); | int vcpu_id = PCPU_ID_GET(cpu); | ||||
int error; | int error; | ||||
struct evtchn_bind_virq bind_virq = { .virq = isrc->xi_virq, | struct evtchn_bind_virq bind_virq = { .virq = isrc->xi_virq, | ||||
.vcpu = vcpu_id }; | .vcpu = vcpu_id }; | ||||
mtx_assert(&xen_intr_isrc_lock, MA_OWNED); | |||||
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, | error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, | ||||
&bind_virq); | &bind_virq); | ||||
if (error != 0) | if (error != 0) | ||||
panic("unable to rebind xen VIRQ#%d: %d", isrc->xi_virq, error); | panic("unable to rebind xen VIRQ#%d: %d", isrc->xi_virq, error); | ||||
isrc->xi_port = bind_virq.port; | isrc->xi_port = bind_virq.port; | ||||
} | } | ||||
static void | static void | ||||
xen_intr_rebind_isrc(struct xenisrc *isrc) | xen_intr_rebind_isrc(struct xenisrc *isrc) | ||||
{ | { | ||||
int cpu = isrc->xi_cpu; | int cpu = isrc->xi_cpu; | ||||
int error; | int error; | ||||
mtx_assert(&xen_intr_isrc_lock, MA_OWNED); | |||||
switch (isrc->xi_type) { | switch (isrc->xi_type) { | ||||
case EVTCHN_TYPE_IPI: | case EVTCHN_TYPE_IPI: | ||||
xen_rebind_ipi(isrc); | xen_rebind_ipi(isrc); | ||||
break; | break; | ||||
case EVTCHN_TYPE_VIRQ: | case EVTCHN_TYPE_VIRQ: | ||||
xen_rebind_virq(isrc); | xen_rebind_virq(isrc); | ||||
break; | break; | ||||
default: | default: | ||||
Show All 30 Lines | CPU_FOREACH(i) { | ||||
memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0, | memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0, | ||||
sizeof(pcpu->evtchn_enabled)); | sizeof(pcpu->evtchn_enabled)); | ||||
} | } | ||||
/* Mask all event channels. */ | /* Mask all event channels. */ | ||||
for (i = 0; i < nitems(s->evtchn_mask); i++) | for (i = 0; i < nitems(s->evtchn_mask); i++) | ||||
atomic_store_rel_long(&s->evtchn_mask[i], ~0); | atomic_store_rel_long(&s->evtchn_mask[i], ~0); | ||||
/* Protect xen_intr_port_to_isrc[] / ->xi_port */ | |||||
mtx_lock(&xen_intr_isrc_lock); | |||||
/* Clear existing port mappings */ | /* Clear existing port mappings */ | ||||
for (isrc_idx = 0; isrc_idx < NR_EVENT_CHANNELS; ++isrc_idx) | for (isrc_idx = 0; isrc_idx < NR_EVENT_CHANNELS; ++isrc_idx) | ||||
if (xen_intr_port_to_isrc[isrc_idx] != NULL) | if (xen_intr_port_to_isrc[isrc_idx] != NULL) | ||||
xen_intr_port_to_isrc[isrc_idx]->xi_port = ~0; | xen_intr_port_to_isrc[isrc_idx]->xi_port = ~0; | ||||
/* Remap in-use isrcs, using xen_intr_port_to_isrc as listing */ | /* Remap in-use isrcs, using xen_intr_port_to_isrc as listing */ | ||||
for (isrc_idx = 0; isrc_idx < NR_EVENT_CHANNELS; ++isrc_idx) { | for (isrc_idx = 0; isrc_idx < NR_EVENT_CHANNELS; ++isrc_idx) { | ||||
struct xenisrc *cur = xen_intr_port_to_isrc[isrc_idx]; | struct xenisrc *cur = xen_intr_port_to_isrc[isrc_idx]; | ||||
Show All 20 Lines | do { | ||||
xen_intr_port_to_isrc[cur->xi_port] = cur; | xen_intr_port_to_isrc[cur->xi_port] = cur; | ||||
evtchn_unmask_port(cur->xi_port); | evtchn_unmask_port(cur->xi_port); | ||||
cur = next; | cur = next; | ||||
} while (cur != NULL); | } while (cur != NULL); | ||||
} | } | ||||
/* Done with xen_intr_port_to_isrc[] / ->xi_port */ | |||||
mtx_unlock(&xen_intr_isrc_lock); | |||||
} | } | ||||
/** | /** | ||||
* Disable a Xen interrupt source. | * Disable a Xen interrupt source. | ||||
* | * | ||||
* \param isrc The interrupt source to disable. | * \param isrc The interrupt source to disable. | ||||
*/ | */ | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 582 Lines • Show Last 20 Lines |