From: chris hyser Date: Thu, 4 Feb 2016 21:14:43 +0000 (-0800) Subject: sparc64: enable "relaxed ordering" in IOMMU mappings X-Git-Tag: v4.1.12-92~163^2~13 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ae8a7d4e6a157092cb998b51b1ce36a50d1faf25;p=users%2Fjedix%2Flinux-maple.git sparc64: enable "relaxed ordering" in IOMMU mappings Enable relaxed ordering for memory writes in IOMMU TSB entry from dma_4v_map_page() and dma_4v_map_sg() when dma_attrs DMA_ATTR_WEAK_ORDERING is set. This requires vPCI version 2.0 API. Orabug: 19245907 Signed-off-by: Chris Hyser (cherry picked from commit d61b9f04493d2a0508c58b6f663c86d6441e1c42) --- diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 83843ef5c895f..1f2f205c95b9f 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -103,6 +103,10 @@ static long iommu_batch_flush(struct iommu_batch *p) while (npages != 0) { long num; + /* VPCI maj=1, min=[0,1] only supports read and write */ + if (vpci_major < 2) + prot &= (HV_PCI_MAP_ATTR_READ | HV_PCI_MAP_ATTR_WRITE); + num = pci_sun4v_iommu_map(devhandle, HV_PCI_TSBID(0, entry), npages, prot, __pa(pglist)); if (unlikely(num < 0)) { @@ -166,6 +170,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, struct dma_attrs *attrs) { unsigned long flags, order, first_page, npages, n; + unsigned long prot = 0; struct iommu *iommu; struct page *page; void *ret; @@ -179,6 +184,9 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, npages = size >> IO_PAGE_SHIFT; + if (dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) + prot = HV_PCI_MAP_ATTR_RELAXED_ORDER; + nid = dev->archdata.numa_node; page = alloc_pages_node(nid, gfp, order); if (unlikely(!page)) @@ -202,7 +210,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, local_irq_save(flags); iommu_batch_start(dev, - (HV_PCI_MAP_ATTR_READ | + (HV_PCI_MAP_ATTR_READ | prot | HV_PCI_MAP_ATTR_WRITE), entry); @@ -338,6 +346,9 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, if (direction != DMA_TO_DEVICE) prot |= HV_PCI_MAP_ATTR_WRITE; + if (dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) + prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER; + local_irq_save(flags); iommu_batch_start(dev, prot, entry); @@ -456,11 +467,14 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, iommu = dev->archdata.iommu; if (nelems == 0 || !iommu) return 0; - + prot = HV_PCI_MAP_ATTR_READ; if (direction != DMA_TO_DEVICE) prot |= HV_PCI_MAP_ATTR_WRITE; + if (dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) + prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER; + outs = s = segstart = &sglist[0]; outcount = 1; incount = nelems;