Commit 5a08e0db authored by Konrad Rzeszutek Wilk's avatar Konrad Rzeszutek Wilk Committed by Ben Hutchings

xen/pciback: For XEN_PCI_OP_disable_msi[|x] only disable if device has MSI(X) enabled.

commit 7cfb905b upstream.

Otherwise just continue on, returning the same values as
previously (return of 0, and op->result has the PIRQ value).

This does not change the behavior of XEN_PCI_OP_disable_msi[|x].

The pci_disable_msi or pci_disable_msix have the checks for
msi_enabled or msix_enabled so they will error out immediately.

However the guest can still call these operations and cause
us to disable the 'ack_intr'. That means the backend IRQ handler
for the legacy interrupt will not respond to interrupts anymore.

This will lead to (if the device is causing an interrupt storm)
for the Linux generic code to disable the interrupt line.

Naturally this will only happen if the device in question
is plugged in on the motherboard on shared level interrupt GSI.

This is part of XSA-157
Reviewed-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent b5f917bf
...@@ -183,20 +183,23 @@ static ...@@ -183,20 +183,23 @@ static
int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev, int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev,
struct pci_dev *dev, struct xen_pci_op *op) struct pci_dev *dev, struct xen_pci_op *op)
{ {
struct xen_pcibk_dev_data *dev_data;
if (unlikely(verbose_request)) if (unlikely(verbose_request))
printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n", printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n",
pci_name(dev)); pci_name(dev));
pci_disable_msi(dev);
if (dev->msi_enabled) {
struct xen_pcibk_dev_data *dev_data;
pci_disable_msi(dev);
dev_data = pci_get_drvdata(dev);
if (dev_data)
dev_data->ack_intr = 1;
}
op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
if (unlikely(verbose_request)) if (unlikely(verbose_request))
printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev), printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev),
op->value); op->value);
dev_data = pci_get_drvdata(dev);
if (dev_data)
dev_data->ack_intr = 1;
return 0; return 0;
} }
...@@ -262,23 +265,27 @@ static ...@@ -262,23 +265,27 @@ static
int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev, int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev,
struct pci_dev *dev, struct xen_pci_op *op) struct pci_dev *dev, struct xen_pci_op *op)
{ {
struct xen_pcibk_dev_data *dev_data;
if (unlikely(verbose_request)) if (unlikely(verbose_request))
printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n", printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n",
pci_name(dev)); pci_name(dev));
pci_disable_msix(dev);
if (dev->msix_enabled) {
struct xen_pcibk_dev_data *dev_data;
pci_disable_msix(dev);
dev_data = pci_get_drvdata(dev);
if (dev_data)
dev_data->ack_intr = 1;
}
/* /*
* SR-IOV devices (which don't have any legacy IRQ) have * SR-IOV devices (which don't have any legacy IRQ) have
* an undefined IRQ value of zero. * an undefined IRQ value of zero.
*/ */
op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
if (unlikely(verbose_request)) if (unlikely(verbose_request))
printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n", pci_name(dev), printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n",
op->value); pci_name(dev), op->value);
dev_data = pci_get_drvdata(dev);
if (dev_data)
dev_data->ack_intr = 1;
return 0; return 0;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment