diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 9c8adbc495..fd02cf2e8d 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -169,9 +169,10 @@ void hvm_pci_intx_deassert( void hvm_gsi_assert(struct domain *d, unsigned int gsi) { + int trig = vioapic_get_trigger_mode(d, gsi); struct hvm_irq *hvm_irq = hvm_domain_irq(d); - if ( gsi >= hvm_irq->nr_gsis ) + if ( gsi >= hvm_irq->nr_gsis || trig < 0 ) { ASSERT_UNREACHABLE(); return; @@ -186,9 +187,10 @@ void hvm_gsi_assert(struct domain *d, unsigned int gsi) * to know if the GSI is pending or not. */ spin_lock(&d->arch.hvm.irq_lock); - if ( !hvm_irq->gsi_assert_count[gsi] ) + if ( trig == VIOAPIC_EDGE_TRIG || !hvm_irq->gsi_assert_count[gsi] ) { - hvm_irq->gsi_assert_count[gsi] = 1; + if ( trig == VIOAPIC_LEVEL_TRIG ) + hvm_irq->gsi_assert_count[gsi] = 1; assert_gsi(d, gsi); } spin_unlock(&d->arch.hvm.irq_lock); @@ -196,11 +198,12 @@ void hvm_gsi_assert(struct domain *d, unsigned int gsi) void hvm_gsi_deassert(struct domain *d, unsigned int gsi) { + int trig = vioapic_get_trigger_mode(d, gsi); struct hvm_irq *hvm_irq = hvm_domain_irq(d); - if ( gsi >= hvm_irq->nr_gsis ) + if ( trig <= VIOAPIC_EDGE_TRIG || gsi >= hvm_irq->nr_gsis ) { - ASSERT_UNREACHABLE(); + ASSERT(trig == VIOAPIC_EDGE_TRIG && gsi < hvm_irq->nr_gsis); return; }