On 2019-05-24 6:40 a.m., Koenig, Christian wrote: > Am 23.05.19 um 17:59 schrieb Christoph Hellwig: >> [CAUTION: External Email] >> >> On Thu, May 23, 2019 at 09:53:53AM -0600, Logan Gunthorpe wrote: >>>> The problem shows up if pci_bus_address() returns a different address >>>> than pci_resource_start(), should be easy to check if that happens. >>>> IIRC it is something mostly seen on embedded SOCs. >>>> >>> I think it's a bit more complicated then that: If you're calling >>> dma_map_resource() to program the IOMMU then I'm pretty sure you'd want >>> to use the pci_resource_start() address as the phys_addr_t. If you're >>> bypassing the root complex (like the current p2pdma code enforces), then >>> you'd simply use a pci_bus_address() directly as the dma_addr and would >>> not program the IOMMU at all seeing it's not involved (which is what is >>> currently done). >> True. What we need is: >> >> if (both device are behind the same root port (using a switch)) { >> use the current direct map + offset code >> } else { >> call ->map_resource() >> } > > Sounds sane to me as well. > > But since I don't have a struct pages backing my PCI BAR I won't be able > to use pci_p2pdma_map_sg. > > How should we work around that? I'd add something like: int pci_p2pdma_map_resource(struct pci_dev *provider, struct device *mapper, phys_addr_t addr, size_t size, enum dma_data_direction dir, unsigned long attrs); But keep in mind we have to update pci_p2pdma_map_sg() as well before we can enable the whitelist as there are existing users. The map_sg() command should be able to get the provider device through the pgmap. And that will be easier to do once Dan's patch[1] lands because he creates a private pgmap struct. Logan [1] https://lore.kernel.org/lkml/155727338646.292046.9922678317501435597.stgit@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/T/#u