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

Commit 89bc6a31 authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: mm: dma: Use dma attribute to allow executeable mappings" into msm-4.8

parents a95ebc64 47982c10
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -1276,18 +1276,23 @@ __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
/*
 * Create a mapping in device IO address space for specified pages
 */
static dma_addr_t
__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
static dma_addr_t __iommu_create_mapping(struct device *dev,
					struct page **pages, size_t size,
					unsigned long attrs)
{
	struct dma_iommu_mapping *mapping = dev->archdata.mapping;
	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
	dma_addr_t dma_addr, iova;
	int i, ret;
	int prot = IOMMU_READ | IOMMU_WRITE;

	dma_addr = __alloc_iova(mapping, size);
	if (dma_addr == DMA_ERROR_CODE)
		return dma_addr;

	if (!(attrs & DMA_ATTR_EXEC_MAPPING))
		prot |= IOMMU_NOEXEC;

	iova = dma_addr;
	for (i = 0; i < count; ) {
		unsigned int next_pfn = page_to_pfn(pages[i]) + 1;
@@ -1299,8 +1304,7 @@ __iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
				break;

		len = (j - i) << PAGE_SHIFT;
		ret = iommu_map(mapping->domain, iova, phys, len,
				IOMMU_READ|IOMMU_WRITE|IOMMU_NOEXEC);
		ret = iommu_map(mapping->domain, iova, phys, len, prot);
		if (ret < 0)
			goto fail;
		iova += len;
@@ -1358,7 +1362,8 @@ static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
}

static void *__iommu_alloc_atomic(struct device *dev, size_t size,
				  dma_addr_t *handle, gfp_t gfp)
				  dma_addr_t *handle, gfp_t gfp,
				  unsigned long attrs)
{
	struct page *page;
	struct page **pages;
@@ -1382,7 +1387,7 @@ static void *__iommu_alloc_atomic(struct device *dev, size_t size,
	for (i = 0; i < count ; i++)
		pages[i] = page + i;

	*handle = __iommu_create_mapping(dev, pages, size);
	*handle = __iommu_create_mapping(dev, pages, size, attrs);
	if (*handle == DMA_ERROR_CODE)
		goto err_mapping;

@@ -1414,7 +1419,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
	size = PAGE_ALIGN(size);

	if (!gfpflags_allow_blocking(gfp))
		return __iommu_alloc_atomic(dev, size, handle, gfp);
		return __iommu_alloc_atomic(dev, size, handle, gfp, attrs);

	/*
	 * Following is a work-around (a.k.a. hack) to prevent pages
@@ -1429,7 +1434,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
	if (!pages)
		return NULL;

	*handle = __iommu_create_mapping(dev, pages, size);
	*handle = __iommu_create_mapping(dev, pages, size, attrs);
	if (*handle == DMA_ERROR_CODE)
		goto err_buffer;

@@ -1573,6 +1578,8 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
					dir);

		prot = __dma_direction_to_prot(dir);
		if (!(attrs & DMA_ATTR_EXEC_MAPPING))
			prot |= IOMMU_NOEXEC;

		ret = iommu_map(mapping->domain, iova, phys, len, prot);
		if (ret < 0)
@@ -1685,6 +1692,9 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
		return 0;
	}

	if (!(attrs & DMA_ATTR_EXEC_MAPPING))
		prot |= IOMMU_NOEXEC;

	ret = iommu_map_sg(mapping->domain, iova, sg, nents, prot);
	if (ret != total_length) {
		__free_iova(mapping, iova, total_length);
@@ -1817,6 +1827,8 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev,
		return dma_addr;

	prot = __dma_direction_to_prot(dir);
	if (!(attrs & DMA_ATTR_EXEC_MAPPING))
		prot |= IOMMU_NOEXEC;

	ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len,
			prot);