From 0b653f27bba4ea6ed8b2e97dae257b9954fe4638 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Mon, 4 Jan 2021 17:54:07 -0800 Subject: [PATCH] ANDROID: iommu/dma: Add support fo DMA_ATTR_SYS_CACHE_ONLY IOMMU_SYS_CACHE_ONLY allows buffers for non-coherent devices to be mapped with the correct memory attributes so that the buffers can be cached in the system cache. However, this property is only usable by drivers that invoke the IOMMU API directly; it is not usable by drivers that use the DMA API. Thus, introduce DMA_ATTR_SYS_CACHE_ONLY, so that drivers for non-coherent devices that use the DMA API can use it to specify if they want a buffer to be cached in the system cache. Bug: 176778547 Change-Id: I849d7a3f36b689afd2f6ee400507223fd6395158 Signed-off-by: Isaac J. Manjarres --- drivers/iommu/dma-iommu.c | 2 ++ include/linux/dma-mapping.h | 8 ++++++++ kernel/dma/mapping.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 7f71b6663e99..3c58602e1229 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -432,6 +432,8 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent, if (attrs & DMA_ATTR_PRIVILEGED) prot |= IOMMU_PRIV; + if (attrs & DMA_ATTR_SYS_CACHE_ONLY) + prot |= IOMMU_SYS_CACHE_ONLY; switch (dir) { case DMA_BIDIRECTIONAL: diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 956151052d45..599228bd9bb9 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -61,6 +61,14 @@ */ #define DMA_ATTR_PRIVILEGED (1UL << 9) +/* + * DMA_ATTR_SYS_CACHE_ONLY: used to indicate that the buffer should be mapped + * with the correct memory attributes so that it can be cached in the system + * or last level cache. This is useful for buffers that are being mapped for + * devices that are non-coherent, but can use the system cache. + */ +#define DMA_ATTR_SYS_CACHE_ONLY (1UL << 10) + /* * A dma_addr_t can hold any valid DMA or bus address for the platform. It can * be given to a device to use as a DMA source or target. It is specific to a diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index 51bb8fa8eb89..dd2762027d5f 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -348,6 +348,8 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs) if (attrs & DMA_ATTR_WRITE_COMBINE) return pgprot_writecombine(prot); #endif + if (attrs & DMA_ATTR_SYS_CACHE_ONLY) + return pgprot_syscached(prot); return pgprot_dmacoherent(prot); } #endif /* CONFIG_MMU */