Skip to content

Commit

Permalink
PCI/MSI: Add pci_msi_ignore_mask to prevent writes to MSI/MSI-X Mask …
Browse files Browse the repository at this point in the history
…Bits

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 0e4ccb1 ("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
  • Loading branch information
Yijing Wang authored and Bjorn Helgaas committed Nov 6, 2014
1 parent f114040 commit 38737d8
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 1 deletion.
2 changes: 2 additions & 0 deletions arch/x86/pci/xen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion drivers/pci/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/linux/msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 38737d8

Please sign in to comment.