summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-06-22 14:00:20 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-06-22 14:00:19 -0700
commit47f3f671143084f82bc5cf2bafc3784aa233d0a8 (patch)
tree2276fa010cb639f7860dc4b66d15d24612980883
parent146cbfce78bc6201dd2b777a903626d5e3486fce (diff)
parent1c6a9c972191d3aa249ae23808a858d8e9e6d187 (diff)
Merge "arm64: dma-mapping: fix aliasing issues with non-CMA alloc"
-rw-r--r--arch/arm64/mm/dma-mapping.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 2445db9bbd4f..a41178f8eeea 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -164,6 +164,8 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flags,
struct dma_attrs *attrs)
{
+ void *addr;
+
if (dev == NULL) {
WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
return NULL;
@@ -174,7 +176,6 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
flags |= GFP_DMA;
if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
struct page *page;
- void *addr;
page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
get_order(size));
@@ -184,20 +185,20 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
*dma_handle = phys_to_dma(dev, page_to_phys(page));
addr = page_address(page);
memset(addr, 0, size);
-
- if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs) ||
- dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) {
- /*
- * flush the caches here because we can't later
- */
- __dma_flush_range(addr, addr + size);
- __dma_remap(page, size, 0, true);
- }
-
- return addr;
} else {
- return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
+ addr = swiotlb_alloc_coherent(dev, size, dma_handle, flags);
}
+
+ if (addr && (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs) ||
+ dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs))) {
+ /*
+ * flush the caches here because we can't later
+ */
+ __dma_flush_range(addr, addr + size);
+ __dma_remap(virt_to_page(addr), size, 0, true);
+ }
+
+ return addr;
}
static void __dma_free_coherent(struct device *dev, size_t size,