From eade6f5737810dda6252ded589b75d670fcd8374 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Mon, 4 Jan 2021 17:33:05 -0800 Subject: [PATCH] ANDROID: iommu/io-pgtable-arm: Add support to use system cache with NWA policy There is currently support for non-coherent devices to use the system cache for their buffers by mapping the buffer with the IOMMU_SYS_CACHE_ONLY protection flag. The IOMMU_SYS_CACHE_ONLY_FLAG maps the buffers with a RW-allocate cache policy by default. There are usecases that do not benefit from having a RW allocate policy, but instead benefit from a no write allocate (NWA) policy, while using the system cache. Thus, add support for mapping memory with the attributes required for it to be cached in the system cached, with a NWA policy: MAIR: 0xe4: inner non-cacheable, outer write-back read allocate. Bug: 176778547 Change-Id: I6d2700a19f0f2e61905b3d36b15f60db3ae59b73 Signed-off-by: Isaac J. Manjarres --- drivers/iommu/io-pgtable-arm.c | 17 ++++++++++++----- include/linux/iommu.h | 7 +++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index e3cc3e3ece15..26551937d459 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -111,14 +111,16 @@ #define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) #define ARM_LPAE_MAIR_ATTR_MASK 0xff -#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04 -#define ARM_LPAE_MAIR_ATTR_NC 0x44 -#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA 0xf4 -#define ARM_LPAE_MAIR_ATTR_WBRWA 0xff +#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04ULL +#define ARM_LPAE_MAIR_ATTR_NC 0x44ULL +#define ARM_LPAE_MAIR_ATTR_INC_OWBRANWA 0xe4ULL +#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA 0xf4ULL +#define ARM_LPAE_MAIR_ATTR_WBRWA 0xffULL #define ARM_LPAE_MAIR_ATTR_IDX_NC 0 #define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1 #define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 #define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE 3 +#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA 4 #define ARM_MALI_LPAE_TTBR_ADRMODE_TABLE (3u << 0) #define ARM_MALI_LPAE_TTBR_READ_INNER BIT(2) @@ -418,6 +420,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, else if (prot & IOMMU_SYS_CACHE_ONLY) pte |= (ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE << ARM_LPAE_PTE_ATTRINDX_SHIFT); + else if (prot & IOMMU_SYS_CACHE_ONLY_NWA) + pte |= (ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA + << ARM_LPAE_PTE_ATTRINDX_SHIFT); } if (prot & IOMMU_CACHE) @@ -831,7 +836,9 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) (ARM_LPAE_MAIR_ATTR_DEVICE << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV)) | (ARM_LPAE_MAIR_ATTR_INC_OWBRWA - << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE)); + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE)) | + (ARM_LPAE_MAIR_ATTR_INC_OWBRANWA + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA)); cfg->arm_lpae_s1_cfg.mair = reg; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 58cce94ca40e..6d77694607fb 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -37,6 +37,13 @@ * the last-level or system cache. */ #define IOMMU_SYS_CACHE_ONLY (1 << 6) +/* + * Non-coherent masters can use this page protection flag to set cacheable + * memory attributes with a no write allocation cache policy for only a + * transparent outer level of cache, also known as the last-level or system + * cache. + */ +#define IOMMU_SYS_CACHE_ONLY_NWA (1 << 7) struct iommu_ops; struct iommu_group;