... as that's not really correct, and there are devices which can't
even cope with that. Instead, check whether an MSI IRQ can be masked,
and if it can't, treat it just like a level triggered IO-APIC IRQ.
There's one other bug fix in here, correcting an off-by-one error on
the entry_nr range check in __pci_enable_msix().
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Index: 2008-10-27/xen/arch/x86/irq.c
===================================================================
--- 2008-10-27.orig/xen/arch/x86/irq.c 2008-10-24 11:21:38.000000000 +0200
+++ 2008-10-27/xen/arch/x86/irq.c 2008-11-13 15:31:17.000000000 +0100
@@ -463,14 +463,19 @@ int pirq_acktype(struct domain *d, int i
/*
* Edge-triggered IO-APIC and LAPIC interrupts need no final
* acknowledgement: we ACK early during interrupt processing.
- * MSIs are treated as edge-triggered interrupts.
*/
if ( !strcmp(desc->handler->typename, "IO-APIC-edge") ||
- !strcmp(desc->handler->typename, "local-APIC-edge") ||
- !strcmp(desc->handler->typename, "PCI-MSI") )
+ !strcmp(desc->handler->typename, "local-APIC-edge") )
return ACKTYPE_NONE;
/*
+ * MSIs are treated as edge-triggered interrupts, except
+ * when there is no proper way to mask them.
+ */
+ if ( desc->handler == &pci_msi_type )
+ return msi_maskable_irq(desc->msi_desc) ? ACKTYPE_NONE : ACKTYPE_EOI;
+
+ /*
* Level-triggered IO-APIC interrupts need to be acknowledged on the CPU
* on which they were received. This is because we tickle the LAPIC to EOI.
*/
Index: 2008-10-27/xen/arch/x86/msi.c
===================================================================
--- 2008-10-27.orig/xen/arch/x86/msi.c 2008-10-17 08:29:02.000000000 +0200
+++ 2008-10-27/xen/arch/x86/msi.c 2008-11-13 15:00:21.000000000 +0100
@@ -303,6 +303,13 @@ static void msix_flush_writes(unsigned i
}
}
+int msi_maskable_irq(const struct msi_desc *entry)
+{
+ BUG_ON(!entry);
+ return entry->msi_attrib.type != PCI_CAP_ID_MSI
+ || entry->msi_attrib.maskbit;
+}
+
static void msi_set_mask_bit(unsigned int irq, int flag)
{
struct msi_desc *entry = irq_desc[irq].msi_desc;
@@ -323,8 +330,6 @@ static void msi_set_mask_bit(unsigned in
mask_bits &= ~(1);
mask_bits |= flag;
pci_conf_write32(bus, slot, func, pos, mask_bits);
- } else {
- msi_set_enable(entry->dev, !flag);
}
break;
case PCI_CAP_ID_MSIX:
@@ -654,7 +659,7 @@ static int __pci_enable_msix(struct msi_
pos = pci_find_cap_offset(msi->bus, slot, func, PCI_CAP_ID_MSIX);
control = pci_conf_read16(msi->bus, slot, func, msi_control_reg(pos));
nr_entries = multi_msix_capable(control);
- if (msi->entry_nr > nr_entries)
+ if (msi->entry_nr >= nr_entries)
{
spin_unlock(&pdev->lock);
return -EINVAL;
Index: 2008-10-27/xen/include/asm-x86/msi.h
===================================================================
--- 2008-10-27.orig/xen/include/asm-x86/msi.h 2008-10-17 08:29:02.000000000
+0200
+++ 2008-10-27/xen/include/asm-x86/msi.h 2008-11-13 15:30:20.000000000
+0100
@@ -97,6 +97,8 @@ struct msi_desc {
int remap_index; /* index in interrupt remapping table */
};
+int msi_maskable_irq(const struct msi_desc *);
+
/*
* Assume the maximum number of hot plug slots supported by the system is about
* ten. The worstcase is that each of these slots is hot-added with a device,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|