Changeset View
Changeset View
Standalone View
Standalone View
sys/xen/xen_intr.c
Show First 20 Lines • Show All 720 Lines • ▼ Show 20 Lines | case EVTCHN_TYPE_IPI: | ||||
break; | break; | ||||
case EVTCHN_TYPE_VIRQ: | case EVTCHN_TYPE_VIRQ: | ||||
xen_rebind_virq(isrc); | xen_rebind_virq(isrc); | ||||
break; | break; | ||||
default: | default: | ||||
return; | return; | ||||
} | } | ||||
xen_intr_port_to_isrc[isrc->xi_port] = isrc; | |||||
#ifdef SMP | #ifdef SMP | ||||
isrc->xi_cpu = 0; | isrc->xi_cpu = 0; | ||||
error = xen_intr_assign_cpu(&isrc->xi_intsrc, | error = xen_intr_assign_cpu(&isrc->xi_intsrc, | ||||
cpu_apic_ids[cpu]); | cpu_apic_ids[cpu]); | ||||
if (error) | if (error) | ||||
panic("unable to bind xen intr#%d to CPU#%d: %d", | panic("unable to bind xen intr#%d to CPU#%d: %d", | ||||
isrc->xi_virq, cpu, error); | isrc->xi_virq, cpu, error); | ||||
#endif | #endif | ||||
evtchn_unmask_port(isrc->xi_port); | |||||
} | } | ||||
/** | /** | ||||
* Return this PIC to service after being suspended. | * Return this PIC to service after being suspended. | ||||
*/ | */ | ||||
static void | static void | ||||
xen_intr_resume(struct pic *unused, bool suspend_cancelled) | xen_intr_resume(struct pic *unused, bool suspend_cancelled) | ||||
{ | { | ||||
shared_info_t *s = HYPERVISOR_shared_info; | shared_info_t *s = HYPERVISOR_shared_info; | ||||
struct xenisrc *isrc; | |||||
u_int isrc_idx; | u_int isrc_idx; | ||||
int i; | int i; | ||||
if (suspend_cancelled) | if (suspend_cancelled) | ||||
return; | return; | ||||
/* Reset the per-CPU masks */ | /* Reset the per-CPU masks */ | ||||
CPU_FOREACH(i) { | CPU_FOREACH(i) { | ||||
struct xen_intr_pcpu_data *pcpu; | struct xen_intr_pcpu_data *pcpu; | ||||
pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); | pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); | ||||
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); | ||||
/* Remove port -> isrc mappings */ | /* Clear existing port mappings */ | ||||
memset(xen_intr_port_to_isrc, 0, sizeof(xen_intr_port_to_isrc)); | for (isrc_idx = 0; isrc_idx < NR_EVENT_CHANNELS; ++isrc_idx) | ||||
if (xen_intr_port_to_isrc[isrc_idx] != NULL) | |||||
xen_intr_port_to_isrc[isrc_idx]->xi_port = ~0; | |||||
/* Free unused isrcs and rebind VIRQs and IPIs */ | /* Remap in-use isrcs, using xen_intr_port_to_isrc as listing */ | ||||
for (isrc_idx = 0; isrc_idx < xen_intr_auto_vector_count; isrc_idx++) { | for (isrc_idx = 0; isrc_idx < NR_EVENT_CHANNELS; ++isrc_idx) { | ||||
u_int vector; | struct xenisrc *cur = xen_intr_port_to_isrc[isrc_idx]; | ||||
vector = first_evtchn_irq + isrc_idx; | /* empty or entry already taken care of */ | ||||
isrc = (struct xenisrc *)intr_lookup_source(vector); | if (cur == NULL || cur->xi_port < NR_EVENT_CHANNELS) | ||||
if (isrc != NULL) | continue; | ||||
xen_intr_rebind_isrc(isrc); | |||||
xen_intr_port_to_isrc[isrc_idx] = NULL; | |||||
do { | |||||
struct xenisrc *next; | |||||
KASSERT(cur->xi_port >= NR_EVENT_CHANNELS, | |||||
("%s(): Multiple channels on single intr?", | |||||
__func__)); | |||||
xen_intr_rebind_isrc(cur); | |||||
/* channel type which doesn't get rebound here */ | |||||
if (cur->xi_port >= NR_EVENT_CHANNELS) | |||||
break; | |||||
next = xen_intr_port_to_isrc[cur->xi_port]; | |||||
xen_intr_port_to_isrc[cur->xi_port] = cur; | |||||
evtchn_unmask_port(cur->xi_port); | |||||
cur = next; | |||||
} while (cur != NULL); | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Disable a Xen interrupt source. | * Disable a Xen interrupt source. | ||||
* | * | ||||
* \param isrc The interrupt source to disable. | * \param isrc The interrupt source to disable. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 586 Lines • Show Last 20 Lines |