PCI/MSI: Add pci_msi_ignore_mask to prevent writes to MSI/MSI-X Mask Bits
authorYijing Wang <wangyijing@huawei.com>
Mon, 27 Oct 2014 02:44:36 +0000 (10:44 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 6 Nov 2014 23:34:39 +0000 (16:34 -0700)
MSI-X vector Mask Bits are in MSI-X Tables in PCI memory space.  Xen PV
guests can't write to those tables.  MSI vector Mask Bits are in PCI
configuration space.  Xen PV guests can write to config space, but those
writes are ignored.

Commit 0e4ccb1505a9 ("PCI: Add x86_msi.msi_mask_irq() and
msix_mask_irq()") added a way to override default_mask_msi_irqs() and
default_mask_msix_irqs() so they can be no-ops in Xen guests, but this is
more complicated than necessary.

Add "pci_msi_ignore_mask" in the core PCI MSI code.  If set,
default_mask_msi_irqs() and default_mask_msix_irqs() return without doing
anything.  This is less flexible, but much simpler.

[bhelgaas: changelog]
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: David Vrabel <david.vrabel@citrix.com>
CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: xen-devel@lists.xenproject.org
arch/x86/pci/xen.c
drivers/pci/msi.c
include/linux/msi.h

index 093f5f4272d340be4307fd93f3d6e2b7d34515f0..5ef62ed20ba43f7a4c6ef186aadd7fc76dd38125 100644 (file)
@@ -427,6 +427,7 @@ int __init pci_xen_init(void)
        x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
        x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
        x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+       pci_msi_ignore_mask = 1;
 #endif
        return 0;
 }
@@ -508,6 +509,7 @@ int __init pci_xen_initial_domain(void)
        x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
        x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
        x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+       pci_msi_ignore_mask = 1;
 #endif
        xen_setup_acpi_sci();
        __acpi_register_gsi = acpi_register_gsi_xen;
index 9fab30af0e75abdcec135707363951d7e9e26f8c..066c2fb9763a66051afcdf0ae4e63948b95dbd71 100644 (file)
@@ -23,6 +23,7 @@
 #include "pci.h"
 
 static int pci_msi_enable = 1;
+int pci_msi_ignore_mask;
 
 #define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)
 
@@ -167,7 +168,7 @@ u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
 {
        u32 mask_bits = desc->masked;
 
-       if (!desc->msi_attrib.maskbit)
+       if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
                return 0;
 
        mask_bits &= ~mask;
@@ -199,6 +200,10 @@ u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
        u32 mask_bits = desc->masked;
        unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
                                                PCI_MSIX_ENTRY_VECTOR_CTRL;
+
+       if (pci_msi_ignore_mask)
+               return 0;
+
        mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
        if (flag)
                mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
index 44f4746d033b9afc0db8f81ddefa72e778a51efb..86dc501a15345846db405ef4470b5194637cedca 100644 (file)
@@ -10,6 +10,7 @@ struct msi_msg {
        u32     data;           /* 16 bits of msi message data */
 };
 
+extern int pci_msi_ignore_mask;
 /* Helper functions */
 struct irq_data;
 struct msi_desc;