Skip to content

Commit

Permalink
PCI: Introduce pci_real_dma_dev()
Browse files Browse the repository at this point in the history
The current DMA alias implementation requires the aliased device be on the
same PCI bus as the requester ID.  Add an arch-specific mechanism to point
to another PCI device when doing mapping and PCI DMA alias search.  The
default case returns the actual device.

Link: https://lore.kernel.org/r/1579613871-301529-4-git-send-email-jonathan.derrick@intel.com
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Christoph Hellwig <hch@lst.de>
  • Loading branch information
Jon Derrick authored and bjorn-helgaas committed Jan 24, 2020
1 parent 34067c5 commit 2856ba6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
10 changes: 10 additions & 0 deletions arch/x86/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,3 +736,13 @@ int pci_ext_cfg_avail(void)
else
return 0;
}

#if IS_ENABLED(CONFIG_VMD)
struct pci_dev *pci_real_dma_dev(struct pci_dev *dev)
{
if (is_vmd(dev->bus))
return to_pci_sysdata(dev->bus)->vmd_dev;

return dev;
}
#endif
19 changes: 18 additions & 1 deletion drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -6033,7 +6033,9 @@ bool pci_devs_are_dma_aliases(struct pci_dev *dev1, struct pci_dev *dev2)
return (dev1->dma_alias_mask &&
test_bit(dev2->devfn, dev1->dma_alias_mask)) ||
(dev2->dma_alias_mask &&
test_bit(dev1->devfn, dev2->dma_alias_mask));
test_bit(dev1->devfn, dev2->dma_alias_mask)) ||
pci_real_dma_dev(dev1) == dev2 ||
pci_real_dma_dev(dev2) == dev1;
}

bool pci_device_is_present(struct pci_dev *pdev)
Expand All @@ -6057,6 +6059,21 @@ void pci_ignore_hotplug(struct pci_dev *dev)
}
EXPORT_SYMBOL_GPL(pci_ignore_hotplug);

/**
* pci_real_dma_dev - Get PCI DMA device for PCI device
* @dev: the PCI device that may have a PCI DMA alias
*
* Permits the platform to provide architecture-specific functionality to
* devices needing to alias DMA to another PCI device on another PCI bus. If
* the PCI device is on the same bus, it is recommended to use
* pci_add_dma_alias(). This is the default implementation. Architecture
* implementations can override this.
*/
struct pci_dev __weak *pci_real_dma_dev(struct pci_dev *dev)
{
return dev;
}

resource_size_t __weak pcibios_default_alignment(void)
{
return 0;
Expand Down
6 changes: 6 additions & 0 deletions drivers/pci/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
struct pci_bus *bus;
int ret;

/*
* The device may have an explicit alias requester ID for DMA where the
* requester is on another PCI bus.
*/
pdev = pci_real_dma_dev(pdev);

ret = fn(pdev, pci_dev_id(pdev), data);
if (ret)
return ret;
Expand Down
1 change: 1 addition & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size);
int pci_select_bars(struct pci_dev *dev, unsigned long flags);
bool pci_device_is_present(struct pci_dev *pdev);
void pci_ignore_hotplug(struct pci_dev *dev);
struct pci_dev *pci_real_dma_dev(struct pci_dev *dev);

int __printf(6, 7) pci_request_irq(struct pci_dev *dev, unsigned int nr,
irq_handler_t handler, irq_handler_t thread_fn, void *dev_id,
Expand Down

0 comments on commit 2856ba6

Please sign in to comment.