aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYijing Wang <wangyijing@huawei.com>2014-10-26 22:44:36 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-11-06 18:34:39 -0500
commit38737d82f9f0168955f9944c3f8bd3bb262c7e88 (patch)
treed43a3bc4a84dad0e3a178f74478ea6996c0773c8 /drivers
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (diff)
PCI/MSI: Add pci_msi_ignore_mask to prevent writes to MSI/MSI-X Mask 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 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
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/msi.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9fab30af0e75..066c2fb9763a 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,7 @@
23#include "pci.h" 23#include "pci.h"
24 24
25static int pci_msi_enable = 1; 25static int pci_msi_enable = 1;
26int pci_msi_ignore_mask;
26 27
27#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) 28#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)
28 29
@@ -167,7 +168,7 @@ u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
167{ 168{
168 u32 mask_bits = desc->masked; 169 u32 mask_bits = desc->masked;
169 170
170 if (!desc->msi_attrib.maskbit) 171 if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
171 return 0; 172 return 0;
172 173
173 mask_bits &= ~mask; 174 mask_bits &= ~mask;
@@ -199,6 +200,10 @@ u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
199 u32 mask_bits = desc->masked; 200 u32 mask_bits = desc->masked;
200 unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + 201 unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
201 PCI_MSIX_ENTRY_VECTOR_CTRL; 202 PCI_MSIX_ENTRY_VECTOR_CTRL;
203
204 if (pci_msi_ignore_mask)
205 return 0;
206
202 mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; 207 mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
203 if (flag) 208 if (flag)
204 mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; 209 mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;