On 03/04/17 14:15, Jayachandran C wrote: > Add a new quirk flag PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT to limit the DMA > alias search to go no further than the bridge where the IOMMU unit is > attached. > > The flag will be used to indicate a bridge device which forwards the > address translation requests to the IOMMU, i.e where the interrupt and > DMA requests leave the PCIe hierarchy and go into the system blocks. > > Usually this happens at the PCI RC, so this flag is not needed. But > on systems where there are bridges that introduce aliases above the > "real" root bridge, this flag is needed to ensure that the function > pci_for_each_dma_alias() works correctly. > > The function pci_for_each_dma_alias() is updated to stop when it see a > bridge with this flag set. As it seems to have been me positing most of the alternative suggestions, which have indeed turned out to have holes in (no, I can't see how we'd cleanly fix pci_device_group() either), I'll stand by my earlier "(I have no actual objection to this patch, though, [...])": Reviewed-by: Robin Murphy <robin.murphy@xxxxxxx> > Signed-off-by: Jayachandran C <jnair@xxxxxxxxxxxxxxxxxx> > --- > drivers/pci/search.c | 4 ++++ > include/linux/pci.h | 2 ++ > 2 files changed, 6 insertions(+) > > diff --git a/drivers/pci/search.c b/drivers/pci/search.c > index 33e0f03..4c6044a 100644 > --- a/drivers/pci/search.c > +++ b/drivers/pci/search.c > @@ -60,6 +60,10 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, > > tmp = bus->self; > > + /* stop at bridge where translation unit is associated */ > + if (tmp->dev_flags & PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT) > + return ret; > + > /* > * PCIe-to-PCI/X bridges alias transactions from downstream > * devices using the subordinate bus number (PCI Express to > diff --git a/include/linux/pci.h b/include/linux/pci.h > index eb3da1a..3f596ac 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -178,6 +178,8 @@ enum pci_dev_flags { > PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7), > /* Get VPD from function 0 VPD */ > PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8), > + /* a non-root bridge where translation occurs, stop alias search here */ > + PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT = (__force pci_dev_flags_t) (1 << 9), > }; > > enum pci_irq_reroute_variant { >