65 lines
2.2 KiB
Diff
65 lines
2.2 KiB
Diff
From e9ab9e04ed76ef06b4ba9a30b3724ca563fdf1fa Mon Sep 17 00:00:00 2001
|
|
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
|
Date: Mon, 2 Nov 2015 18:13:27 -0500
|
|
Subject: [PATCH v2 XSA157 5/5] xen/pciback: Don't allow MSI-X ops if
|
|
PCI_COMMAND_MEMORY is not set.
|
|
|
|
commit f598282f51 ("PCI: Fix the NIU MSI-X problem in a better way")
|
|
teaches us that dealing with MSI-X can be troublesome.
|
|
|
|
Further checks in the MSI-X architecture shows that if the
|
|
PCI_COMMAND_MEMORY bit is turned of in the PCI_COMMAND we
|
|
may not be able to access the BAR (since they are memory regions).
|
|
|
|
Since the MSI-X tables are located in there.. that can lead
|
|
to us causing PCIe errors. Inhibit us performing any
|
|
operation on the MSI-X unless the MEMORY bit is set.
|
|
|
|
Note that Xen hypervisor with:
|
|
"x86/MSI-X: access MSI-X table only after having enabled MSI-X"
|
|
will return:
|
|
xen_pciback: 0000:0a:00.1: error -6 enabling MSI-X for guest 3!
|
|
|
|
When the generic MSI code tries to setup the PIRQ without
|
|
MEMORY bit set. Which means with later versions of Xen
|
|
(4.6) this patch is not neccessary.
|
|
|
|
This is part of XSA-157
|
|
|
|
CC: stable@vger.kernel.org
|
|
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
|
---
|
|
drivers/xen/xen-pciback/pciback_ops.c | 8 +++++++-
|
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
|
|
index 648c09c..edb9357 100644
|
|
--- a/drivers/xen/xen-pciback/pciback_ops.c
|
|
+++ b/drivers/xen/xen-pciback/pciback_ops.c
|
|
@@ -212,6 +212,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
|
|
struct xen_pcibk_dev_data *dev_data;
|
|
int i, result;
|
|
struct msix_entry *entries;
|
|
+ u16 cmd;
|
|
|
|
if (unlikely(verbose_request))
|
|
printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n",
|
|
@@ -223,7 +224,12 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
|
|
if (dev->msix_enabled)
|
|
return -EALREADY;
|
|
|
|
- if (dev->msi_enabled)
|
|
+ /*
|
|
+ * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
|
|
+ * to access the BARs where the MSI-X entries reside.
|
|
+ */
|
|
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
|
+ if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
|
|
return -ENXIO;
|
|
|
|
entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
|
|
--
|
|
2.1.0
|
|
|