aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-01-21 14:44:43 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-01-21 14:44:43 +0000
commit5f4c1bb65edbbb91a5d173dc9fa7f1541a2cb826 (patch)
tree513382532ca4b7751a2f7a56950e4193e00f6a13
parent137e278117d2c8b884077e1507c8d5f634c98441 (diff)
downloadxen-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.c5
-rw-r--r--xen/arch/x86/irq.c8
-rw-r--r--xen/arch/x86/physdev.c11
-rw-r--r--xen/include/asm-x86/irq.h1
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,