@@ -251,6 +251,7 @@ int iommu_add_dt_pci_sideband_ids(struct pci_dev *pdev)
struct device *dev = pci_to_dev(pdev);
const struct dt_device_node *np;
int rc = NO_IOMMU;
+ unsigned int devfn = pdev->devfn;
if ( !iommu_enabled )
return NO_IOMMU;
@@ -268,21 +269,27 @@ int iommu_add_dt_pci_sideband_ids(struct pci_dev *pdev)
if ( !np )
return -ENODEV;
- /*
- * According to the Documentation/devicetree/bindings/pci/pci-iommu.txt
- * from Linux.
- */
- rc = dt_map_id(np, PCI_BDF(pdev->bus, pdev->devfn), "iommu-map",
- "iommu-map-mask", &iommu_spec.np, iommu_spec.args);
- if ( rc )
- return (rc == -ENODEV) ? NO_IOMMU : rc;
+ do {
+ /*
+ * According to the Documentation/devicetree/bindings/pci/pci-iommu.txt
+ * from Linux.
+ */
+ rc = dt_map_id(np, PCI_BDF(pdev->bus, devfn), "iommu-map",
+ "iommu-map-mask", &iommu_spec.np, iommu_spec.args);
+ if ( rc )
+ return (rc == -ENODEV) ? NO_IOMMU : rc;
- rc = iommu_dt_xlate(dev, &iommu_spec);
- if ( rc < 0 )
- {
- iommu_fwspec_free(dev);
- return -EINVAL;
+ rc = iommu_dt_xlate(dev, &iommu_spec);
+ if ( rc < 0 )
+ {
+ iommu_fwspec_free(dev);
+ return -EINVAL;
+ }
+
+ devfn += pdev->phantom_stride;
}
+ while ( (devfn != pdev->devfn) &&
+ (PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn)) );
return rc;
}
Handle phantom functions in iommu_add_dt_pci_sideband_ids(). Each phantom function will have a unique requestor ID (RID)/BDF. On ARM, we need to map/translate the RID/BDF to an AXI stream ID for each phantom function according to the pci-iommu device tree mapping [1]. The RID/BDF -> AXI stream ID mapping in DT could allow phantom devices (i.e. devices with phantom functions) to use different AXI stream IDs based on the (phantom) function. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/pci/pci-iommu.txt Signed-off-by: Stewart Hildebrand <stewart.hildebrand@amd.com> --- v3->v4: * s/iommu_dt_pci_map_id/dt_map_id/ v2->v3: * new patch title (was: iommu/arm: iommu_add_dt_pci_device phantom handling) * rework loop to reduce duplication * s/iommu_fwspec_free(pci_to_dev(pdev))/iommu_fwspec_free(dev)/ v1->v2: * new patch --- xen/drivers/passthrough/device_tree.c | 33 ++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-)