Zhang, Xiantao
2009-Oct-27 14:04 UTC
[Xen-devel] x86: vioapic: fix remote irr bit setting for level triggered interrupts.
It may get irq stuck if miss to clear remote irr bit for some RTE entries for the level triggered interrupts. Currently, only the first matched entry is cleared, and it is not enough, especially when guest adopts per-cpu vector(two or more entries are assigned with same vector). Xiantao x86: vioapic: fix remote irr bit setting for level triggered interrupts. Clear all entries'' remote irr bits once the RTE entries'' vector field match with EOI message''s vector. Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com> diff -r 5f28661bb2bb xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Mon Oct 19 10:57:58 2009 +0100 +++ b/xen/arch/x86/hvm/vioapic.c Tue Oct 27 21:42:51 2009 +0800 @@ -384,17 +384,6 @@ void vioapic_irq_positive_edge(struct do } } -static int get_eoi_gsi(struct hvm_hw_vioapic *vioapic, int vector) -{ - int i; - - for ( i = 0; i < VIOAPIC_NUM_PINS; i++ ) - if ( vioapic->redirtbl[i].fields.vector == vector ) - return i; - - return -1; -} - void vioapic_update_EOI(struct domain *d, int vector) { struct hvm_hw_vioapic *vioapic = domain_vioapic(d); @@ -403,33 +392,28 @@ void vioapic_update_EOI(struct domain *d int gsi; spin_lock(&d->arch.hvm_domain.irq_lock); - - if ( (gsi = get_eoi_gsi(vioapic, vector)) == -1 ) - { - gdprintk(XENLOG_WARNING, "Can''t find redir item for %d EOI\n", vector); - goto out; - } - - ent = &vioapic->redirtbl[gsi]; - - ent->fields.remote_irr = 0; - - if ( iommu_enabled ) - { - spin_unlock(&d->arch.hvm_domain.irq_lock); - hvm_dpci_eoi(current->domain, gsi, ent); - spin_lock(&d->arch.hvm_domain.irq_lock); - } - - if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) && - !ent->fields.mask && - hvm_irq->gsi_assert_count[gsi] ) - { - ent->fields.remote_irr = 1; - vioapic_deliver(vioapic, gsi); - } - - out: + for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ ) { + ent = &vioapic->redirtbl[gsi]; + if ( ent->fields.vector != vector ) + continue; + + ent->fields.remote_irr = 0; + + if ( iommu_enabled ) + { + spin_unlock(&d->arch.hvm_domain.irq_lock); + hvm_dpci_eoi(d, gsi, ent); + spin_lock(&d->arch.hvm_domain.irq_lock); + } + + if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) && + !ent->fields.mask && + hvm_irq->gsi_assert_count[gsi] ) + { + ent->fields.remote_irr = 1; + vioapic_deliver(vioapic, gsi); + } + } spin_unlock(&d->arch.hvm_domain.irq_lock); } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel