diff options
author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-06-22 14:00:20 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-06-22 14:00:19 -0700 |
commit | 47f3f671143084f82bc5cf2bafc3784aa233d0a8 (patch) | |
tree | 2276fa010cb639f7860dc4b66d15d24612980883 | |
parent | 146cbfce78bc6201dd2b777a903626d5e3486fce (diff) | |
parent | 1c6a9c972191d3aa249ae23808a858d8e9e6d187 (diff) |
Merge "arm64: dma-mapping: fix aliasing issues with non-CMA alloc"
-rw-r--r-- | arch/arm64/mm/dma-mapping.c | 27 |
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, |