Skip to content

Commit

Permalink
x86/PCI: Don't alloc pcibios-irq when MSI is enabled
Browse files Browse the repository at this point in the history
The pcibios-irq and MSI both use dev->irq to store the IRQ number.  While
the MSI code checks for that and frees the pcibios-irq before overwriting
dev->irq, the pcibios_alloc_irq() function does not.

Usually this is not a problem, as the pcibios-irq is allocated before probe
time of the device and the MSI IRQ is allocted from the driver's probe
path.

But there are PCI devices handled by the core kernel and not by a standard
PCI driver, like the AMD IOMMU for example.  For the AMD IOMMU a normal PCI
device driver does not make sense, because a driver can be forcibly unbound
from its device, which is not a good idea for an IOMMU.

Nevertheless the PCI core code tries to match the PCI device implementing
the AMD IOMMU against drivers, and allocates/frees a pcibios IRQ every time
it tries out a new driver.  This overwrites the dev->irq field set by
pci_enable_msi() and sets it to 0 in the end (because the probe fails and
the pcibios-irq is freed again).

On suspend/resume this breaks the kernel, because the IRQ descriptor for
IRQ 0 is NULL.

Fix this by not allocating a pcibios-irq when MSI is already active.  This
also has the benefit, that a device claimed by the core kernel can not be
probed by a PCI driver later.

Reported-by: Borislav Petkov <[email protected]>
Signed-off-by: Joerg Roedel <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Reviewed-by: Thomas Gleixner <[email protected]>
Cc: Jiang Liu <[email protected]>
  • Loading branch information
joergroedel authored and bjorn-helgaas committed Oct 21, 2015
1 parent a867606 commit 8affb48
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions arch/x86/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,14 @@ int pcibios_add_device(struct pci_dev *dev)

int pcibios_alloc_irq(struct pci_dev *dev)
{
/*
* If the PCI device was already claimed by core code and has
* MSI enabled, probing of the pcibios IRQ will overwrite
* dev->irq. So bail out if MSI is already enabled.
*/
if (pci_dev_msi_enabled(dev))
return -EBUSY;

return pcibios_enable_irq(dev);
}

Expand Down

0 comments on commit 8affb48

Please sign in to comment.