Commit e9e256df authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/host-vmd' into next

* pci/host-vmd:
  iommu/vt-d: Prevent VMD child devices from being remapping targets
  x86/PCI: Use is_vmd() rather than relying on the domain number
  x86/PCI: Move VMD quirk to x86 fixups
  MAINTAINERS: Add Jonathan Derrick as VMD maintainer
  PCI: vmd: Remove IRQ affinity so we can allocate more IRQs
  PCI: vmd: Free up IRQs on suspend path
  PCI: vmd: Assign vector zero to all bridges
  PCI: vmd: Reserve IRQ pre-vector for better affinity
parents 08d20f9f 5823e330
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10090,6 +10090,7 @@ F: drivers/pci/dwc/*imx6*

PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
M:	Keith Busch <keith.busch@intel.com>
M:	Jonathan Derrick <jonathan.derrick@intel.com>
L:	linux-pci@vger.kernel.org
S:	Supported
F:	drivers/pci/host/vmd.c
+17 −0
Original line number Diff line number Diff line
@@ -618,3 +618,20 @@ static void quirk_apple_mbp_poweroff(struct pci_dev *pdev)
		dev_info(dev, "can't work around MacBook Pro poweroff issue\n");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff);

/*
 * VMD-enabled root ports will change the source ID for all messages
 * to the VMD device. Rather than doing device matching with the source
 * ID, the AER driver should traverse the child device tree, reading
 * AER registers to find the faulting device.
 */
static void quirk_no_aersid(struct pci_dev *pdev)
{
	/* VMD Domain */
	if (is_vmd(pdev->bus))
		pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID;
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
+7 −0
Original line number Diff line number Diff line
@@ -901,6 +901,13 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
		struct pci_dev *pf_pdev;

		pdev = to_pci_dev(dev);

#ifdef CONFIG_X86
		/* VMD child devices currently cannot be handled individually */
		if (is_vmd(pdev->bus))
			return NULL;
#endif

		/* VFs aren't listed in scope tables; we need to look up
		 * the PF instead to find the IOMMU. */
		pf_pdev = pci_physfn(pdev);
+17 −2
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *d
	int i, best = 1;
	unsigned long flags;

	if (!desc->msi_attrib.is_msix || vmd->msix_count == 1)
	if (pci_is_bridge(msi_desc_to_pci_dev(desc)) || vmd->msix_count == 1)
		return &vmd->irqs[0];

	raw_spin_lock_irqsave(&list_lock, flags);
@@ -697,7 +697,7 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
		return -ENODEV;

	vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count,
					PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
					PCI_IRQ_MSIX);
	if (vmd->msix_count < 0)
		return vmd->msix_count;

@@ -755,6 +755,11 @@ static void vmd_remove(struct pci_dev *dev)
static int vmd_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct vmd_dev *vmd = pci_get_drvdata(pdev);
	int i;

	for (i = 0; i < vmd->msix_count; i++)
                devm_free_irq(dev, pci_irq_vector(pdev, i), &vmd->irqs[i]);

	pci_save_state(pdev);
	return 0;
@@ -763,6 +768,16 @@ static int vmd_suspend(struct device *dev)
static int vmd_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct vmd_dev *vmd = pci_get_drvdata(pdev);
	int err, i;

	for (i = 0; i < vmd->msix_count; i++) {
		err = devm_request_irq(dev, pci_irq_vector(pdev, i),
				       vmd_irq, IRQF_NO_THREAD,
				       "vmd", &vmd->irqs[i]);
		if (err)
			return err;
	}

	pci_restore_state(pdev);
	return 0;
+0 −17
Original line number Diff line number Diff line
@@ -4657,23 +4657,6 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);

/*
 * VMD-enabled root ports will change the source ID for all messages
 * to the VMD device. Rather than doing device matching with the source
 * ID, the AER driver should traverse the child device tree, reading
 * AER registers to find the faulting device.
 */
static void quirk_no_aersid(struct pci_dev *pdev)
{
	/* VMD Domain */
	if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000)
		pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID;
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);

/* FLR may cause some 82579 devices to hang. */
static void quirk_intel_no_flr(struct pci_dev *dev)
{