aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vioapic.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-10-28 10:59:14 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-10-28 10:59:14 +0000
commitfff38b68f88c136441d5f5495c5b0a24bc8c207d (patch)
treeaedba315796770467a1c74ab6b80091e04180cc2 /xen/arch/x86/hvm/vioapic.c
parentde349fe6b08c398a694818e5393111cc2dbecf9d (diff)
downloadxen-fff38b68f88c136441d5f5495c5b0a24bc8c207d.tar.gz
xen-fff38b68f88c136441d5f5495c5b0a24bc8c207d.tar.bz2
xen-fff38b68f88c136441d5f5495c5b0a24bc8c207d.zip
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>
Diffstat (limited to 'xen/arch/x86/hvm/vioapic.c')
-rw-r--r--xen/arch/x86/hvm/vioapic.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 5a4d82730e..9c0033a23e 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -384,17 +384,6 @@ void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
}
}
-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);
@@ -404,32 +393,30 @@ void vioapic_update_EOI(struct domain *d, int vector)
spin_lock(&d->arch.hvm_domain.irq_lock);
- if ( (gsi = get_eoi_gsi(vioapic, vector)) == -1 )
+ for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ )
{
- gdprintk(XENLOG_WARNING, "Can't find redir item for %d EOI\n", vector);
- goto out;
- }
-
- ent = &vioapic->redirtbl[gsi];
+ ent = &vioapic->redirtbl[gsi];
+ if ( ent->fields.vector != vector )
+ continue;
- ent->fields.remote_irr = 0;
+ 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 ( 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);
+ 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:
spin_unlock(&d->arch.hvm_domain.irq_lock);
}