From 84df8c8f74ec86c239f7aea54ec0d98b0a4a421d Mon Sep 17 00:00:00 2001 From: Liam Mark Date: Thu, 26 Jan 2017 16:46:14 -0800 Subject: [PATCH] arm: dma-mapping: map_page map to nearest page Since the page offset can be greater than the size of a page fix arm_coherent_iommu_map_page so that it maps to nearest page boundary. This both prevents unnecessarily mapping memory we don't need to map and fixes a issue where the unmap wasn't unmapping this extra memory. Change-Id: Iaa69aff7505ee75d1f2e69bb0cda814bc6211bd3 Signed-off-by: Liam Mark Signed-off-by: Patrick Daly Signed-off-by: Charan Teja Reddy Signed-off-by: Vijayanand Jitta Signed-off-by: Qingqing Zhou --- arch/arm/mm/dma-mapping.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 630260a325d7..5443a6c72a63 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1893,7 +1893,11 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *p { struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); dma_addr_t dma_addr; - int ret, prot, len = PAGE_ALIGN(size + offset); + int ret, prot, len, start_offset, map_offset; + + map_offset = offset & ~PAGE_MASK; + start_offset = offset & PAGE_MASK; + len = PAGE_ALIGN(map_offset + size); dma_addr = __alloc_iova(mapping, len); if (dma_addr == DMA_MAPPING_ERROR) @@ -1901,11 +1905,12 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *p prot = __dma_info_to_prot(dir, attrs); - ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, prot); + ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page) + + start_offset, len, prot); if (ret < 0) goto fail; - return dma_addr + offset; + return dma_addr + map_offset; fail: __free_iova(mapping, dma_addr, len); return DMA_MAPPING_ERROR;