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 <lmark@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
Signed-off-by: Charan Teja Reddy <charante@codeaurora.org>
Signed-off-by: Vijayanand Jitta <vjitta@codeaurora.org>
Signed-off-by: Qingqing Zhou <qqzhou@codeaurora.org>
This commit is contained in:
Liam Mark 2017-01-26 16:46:14 -08:00 • committed by Gerrit - the friendly Code Review server
commit 84df8c8f74

View file

@ -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;