Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60695be2 authored by Jacopo Mondi's avatar Jacopo Mondi Committed by Christoph Hellwig
Browse files

dma-mapping: postpone cpu addr translation on mmap



Postpone calling virt_to_page() translation on memory locations not
guaranteed to be backed by a struct page.  Try first to map memory from
the device coherent memory pool, then perform translation if that fails.

On some architectures, specifically SH when configured with the SPARSEMEM
memory model, assuming a struct page is always assigned to a memory
address lead to unexpected hangs during the virtual to page address
translation. This patch fixes that specific issue but applies in the
general case too.

Suggested-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarJacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: default avatarRobin Murphy <robin.murphy@arm.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 41d0bbc7
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -226,7 +226,6 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
#ifndef CONFIG_ARCH_NO_COHERENT_DMA_MMAP
	unsigned long user_count = vma_pages(vma);
	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
	unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
	unsigned long off = vma->vm_pgoff;

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
@@ -234,12 +233,11 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
	if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
		return ret;

	if (off < count && user_count <= (count - off)) {
	if (off < count && user_count <= (count - off))
		ret = remap_pfn_range(vma, vma->vm_start,
				      pfn + off,
				      page_to_pfn(virt_to_page(cpu_addr)) + off,
				      user_count << PAGE_SHIFT,
				      vma->vm_page_prot);
	}
#endif	/* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */

	return ret;