X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fpci%2Fmsi.c;h=402063ff889e651611299d7178385b00abc8c7c1;hb=5f41543eddb09fbc1b05a75f4b6b046225b49e6a;hp=2c1075213beceac6bb0eb75be6aeef7adc8f34d7;hpb=607eeb0b836aa24a6972a460a213c4f87902d403;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 2c1075213bec..402063ff889e 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -530,6 +530,20 @@ out_unroll: return ret; } +static int msi_verify_entries(struct pci_dev *dev) +{ + struct msi_desc *entry; + + list_for_each_entry(entry, &dev->msi_list, list) { + if (!dev->no_64bit_msi || !entry->msg.address_hi) + continue; + dev_err(&dev->dev, "Device has broken 64-bit MSI but arch" + " tried to assign one above 4G\n"); + return -EIO; + } + return 0; +} + /** * msi_capability_init - configure device's MSI capability structure * @dev: pointer to the pci_dev data structure of MSI device function @@ -583,6 +597,13 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) return ret; } + ret = msi_verify_entries(dev); + if (ret) { + msi_mask_irq(entry, mask, ~mask); + free_msi_irqs(dev); + return ret; + } + ret = populate_msi_sysfs(dev); if (ret) { msi_mask_irq(entry, mask, ~mask); @@ -698,6 +719,11 @@ static int msix_capability_init(struct pci_dev *dev, if (ret) goto error; + /* Check if all MSI entries honor device restrictions */ + ret = msi_verify_entries(dev); + if (ret) + goto error; + /* * Some devices require MSI-X to be enabled before we can touch the * MSI-X registers. We need to mask all the vectors to prevent