iommu/io-pgtable: Support non-coherent page tables
authorBjorn Andersson <bjorn.andersson@linaro.org>
Wed, 15 May 2019 23:32:34 +0000 (16:32 -0700)
committerWill Deacon <will@kernel.org>
Tue, 25 Jun 2019 12:26:47 +0000 (13:26 +0100)
Describe the memory related to page table walks as non-cacheable for
iommu instances that are not DMA coherent.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
[will: Use cfg->coherent_walk, fix arm-v7s, ensure outer-shareable for NC]
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c

index 8454de93e356fc3a91bd9a82372652a5074a8f6c..35de9ebb500cf83a5fe0498833efe78311c36ab7 100644 (file)
@@ -789,8 +789,11 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
        /* TTBRs */
        cfg->arm_v7s_cfg.ttbr[0] = virt_to_phys(data->pgd) |
                                   ARM_V7S_TTBR_S | ARM_V7S_TTBR_NOS |
-                                  ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
-                                  ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA);
+                                  (cfg->coherent_walk ?
+                                  (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
+                                   ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA)) :
+                                  (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_NC) |
+                                   ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_NC)));
        cfg->arm_v7s_cfg.ttbr[1] = 0;
        return &data->iop;
 
index 91d0a4228b587a8507447edad1219534d001df32..b4e624afd1bbbcac7f87a764959a2faaf5222b7d 100644 (file)
@@ -806,9 +806,15 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
                return NULL;
 
        /* TCR */
-       reg = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
-             (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
-             (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
+       if (cfg->coherent_walk) {
+               reg = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
+                     (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
+                     (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
+       } else {
+               reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
+                     (ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_IRGN0_SHIFT) |
+                     (ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_ORGN0_SHIFT);
+       }
 
        switch (ARM_LPAE_GRANULE(data)) {
        case SZ_4K: