diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-01-21 14:44:43 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-01-21 14:44:43 +0000 |
commit | 5f4c1bb65edbbb91a5d173dc9fa7f1541a2cb826 (patch) | |
tree | 513382532ca4b7751a2f7a56950e4193e00f6a13 | |
parent | 137e278117d2c8b884077e1507c8d5f634c98441 (diff) | |
download | xen-5f4c1bb65edbbb91a5d173dc9fa7f1541a2cb826.tar.gz xen-5f4c1bb65edbbb91a5d173dc9fa7f1541a2cb826.tar.bz2 xen-5f4c1bb65edbbb91a5d173dc9fa7f1541a2cb826.zip |
x86: Fix unmaskable MSI handling, and also some other EOI-notification issues.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/arch/x86/io_apic.c | 5 | ||||
-rw-r--r-- | xen/arch/x86/irq.c | 8 | ||||
-rw-r--r-- | xen/arch/x86/physdev.c | 11 | ||||
-rw-r--r-- | xen/include/asm-x86/irq.h | 1 |
4 files changed, 17 insertions, 8 deletions
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 43ca13a2ae..3f2c3426ff 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -1554,11 +1554,14 @@ static unsigned int startup_msi_vector(unsigned int vector) static void ack_msi_vector(unsigned int vector) { - ack_APIC_irq(); + if ( msi_maskable_irq(irq_desc[vector].msi_desc) ) + ack_APIC_irq(); /* ACKTYPE_NONE */ } static void end_msi_vector(unsigned int vector) { + if ( !msi_maskable_irq(irq_desc[vector].msi_desc) ) + ack_APIC_irq(); /* ACKTYPE_EOI */ } static void shutdown_msi_vector(unsigned int vector) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index d86ae03d32..ffcb0fcdf9 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -705,6 +705,10 @@ static irq_guest_action_t *__pirq_guest_unbind( spin_lock_irq(&desc->lock); } break; + case ACKTYPE_NONE: + stop_timer(&irq_guest_eoi_timer[vector]); + _irq_guest_eoi(desc); + break; } /* @@ -853,10 +857,6 @@ int map_domain_pirq( ASSERT(spin_is_locked(&pcidevs_lock)); ASSERT(spin_is_locked(&d->event_lock)); - /* XXX Until pcidev and msi locking is fixed. */ - if ( type == MAP_PIRQ_TYPE_MSI ) - return -EINVAL; - if ( !IS_PRIV(current->domain) ) return -EPERM; diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index bb4d08e81b..63ef08893b 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -257,8 +257,15 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) if ( (irq < 0) || (irq >= NR_IRQS) ) break; irq_status_query.flags = 0; - if ( pirq_acktype(v->domain, irq) != 0 ) - irq_status_query.flags |= XENIRQSTAT_needs_eoi; + /* + * Even edge-triggered or message-based IRQs can need masking from + * time to time. If teh guest is not dynamically checking for this + * via the new pirq_eoi_map mechanism, it must conservatively always + * execute the EOI hypercall. In practice, this only really makes a + * difference for maskable MSI sources, and if those are supported + * then dom0 is probably modern anyway. + */ + irq_status_query.flags |= XENIRQSTAT_needs_eoi; if ( pirq_shared(v->domain, irq) ) irq_status_query.flags |= XENIRQSTAT_shared; ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0; diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h index 8765f39061..2f1e59f148 100644 --- a/xen/include/asm-x86/irq.h +++ b/xen/include/asm-x86/irq.h @@ -52,7 +52,6 @@ extern unsigned long io_apic_irqs; extern atomic_t irq_err_count; extern atomic_t irq_mis_count; -int pirq_acktype(struct domain *d, int irq); int pirq_shared(struct domain *d , int irq); int map_domain_pirq(struct domain *d, int pirq, int vector, int type, |