From: Allen Pais Date: Tue, 16 May 2017 07:08:38 +0000 (+0530) Subject: SPARC64: Introduce IOMMU BYPASS method X-Git-Tag: v4.1.12-98.0.20170517_2143~10 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=615d721f4a13bee8bd4c9445ff6d9f8a90ed9410;p=users%2Fjedix%2Flinux-maple.git SPARC64: Introduce IOMMU BYPASS method This change adds IOMMU BYPASS HV API that will allow PCIe devices to bypass IOMMU during DMA map/unmap. Orabug: 25573557 Signed-off-by: Tushar Dave Signed-off-by: Allen Pais --- diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 30ed5d0095ea6..195fc668daeca 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -292,22 +292,20 @@ static dma_addr_t dma_4v_map_page_bypass(struct device *dev, struct page *page, unsigned long prot; unsigned long dma_addr; - BUG_ON(!dev); - pbm = dev->archdata.host_controller; - BUG_ON(!pbm); - devhandle = pbm->devhandle; - if (unlikely(direction == DMA_NONE)) goto bad; prot = HV_PCI_MAP_ATTR_READ; - if (direction != DMA_TO_DEVICE) prot |= HV_PCI_MAP_ATTR_WRITE; + /* VPCI maj=2, min=[0,1] or greater supports relax ordering */ + if (dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs) && vpci_major >= 2) + prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER; + pbm = dev->archdata.host_controller; + devhandle = pbm->devhandle; ra = __pa(page_address(page) + offset); - if (pci_sun4v_iommu_getbypass(devhandle, ra, prot, &dma_addr)) goto bad; @@ -426,21 +424,21 @@ static int dma_4v_map_sg_bypass(struct device *dev, struct scatterlist *sglist, struct scatterlist *s; int i; - BUG_ON(!dev); - pbm = dev->archdata.host_controller; - BUG_ON(!pbm); - devhandle = pbm->devhandle; - if (unlikely(direction == DMA_NONE)) goto bad; prot = HV_PCI_MAP_ATTR_READ; - if (direction != DMA_TO_DEVICE) prot |= HV_PCI_MAP_ATTR_WRITE; + /* VPCI maj=2, min=[0,1] or greater supports relax ordering */ + if (dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs) && vpci_major >= 2) + prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER; + + pbm = dev->archdata.host_controller; + devhandle = pbm->devhandle; for_each_sg(sglist, s, nelems, i) { - ra = (unsigned long) SG_ENT_PHYS_ADDRESS(s); + ra = (unsigned long)SG_ENT_PHYS_ADDRESS(s); if (pci_sun4v_iommu_getbypass(devhandle, ra, prot, &dma_addr)) goto bad; s->dma_address = dma_addr;