static irqreturn_t xpmem_irq_fn(int irq, void * priv_data) { xpmem_segid_t segid = (xpmem_segid_t)priv_data; uint32_t sigs = xpmem_get_and_clear_host_sig_count(xpmem_irq_to_vector(irq)); uint32_t sigs_handled = 0; uint32_t sig = 0; for (sig = 0; sig < sigs; sig++) { sigs_handled += (xpmem_segid_signal(segid) == 0) ? 1 : 0; } return (sigs_handled) ? IRQ_HANDLED : IRQ_NONE; }
int xpmem_alloc_seg_signal(struct xpmem_segment * seg) { int irq; int vector, host_vector; int apic_id; /* Request irq */ irq = xpmem_request_irq(xpmem_irq_fn, (void *)seg->segid); if (irq < 0) return irq; /* Get IDT vector */ vector = xpmem_irq_to_vector(irq); if (vector < 0) { xpmem_release_irq(irq, (void *)seg->segid); return vector; } /* Get hardware IDT vector from host */ host_vector = xpmem_request_host_vector(vector); /* Get hardware apic ID for logical cpu 0*/ apic_id = xpmem_get_host_apic_id(0); if (apic_id < 0) { xpmem_release_host_vector(host_vector); xpmem_release_irq(irq, (void *)seg->segid); return apic_id; } /* Save sigid in seg structure */ seg->sig.irq = irq; seg->sig.vector = host_vector; seg->sig.apic_id = apic_id; return 0; }