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@xxxxxxxxx>
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);
}
fix-remote-irr-setting.patch
Description: fix-remote-irr-setting.patch
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|