Thread (24 messages) 24 messages, 7 authors, 2021-07-26

Re: [PATCH v4 1/3] iommu: io-pgtable: add DART pagetable format

From: Alexander Graf <graf@amazon.com>
Date: 2021-06-28 10:54:42
Also in: linux-arm-kernel, linux-iommu, lkml


On 27.06.21 16:34, Sven Peter wrote:
quoted hunk ↗ jump to hunk
Apple's DART iommu uses a pagetable format that shares some
similarities with the ones already implemented by io-pgtable.c.
Add a new format variant to support the required differences
so that we don't have to duplicate the pagetable handling code.

Signed-off-by: Sven Peter <redacted>
---
  drivers/iommu/io-pgtable-arm.c | 62 ++++++++++++++++++++++++++++++++++
  drivers/iommu/io-pgtable.c     |  1 +
  include/linux/io-pgtable.h     |  7 ++++
  3 files changed, 70 insertions(+)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 87def58e79b5..1dd5c45b4b5b 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -127,6 +127,9 @@
  #define ARM_MALI_LPAE_MEMATTR_IMP_DEF  0x88ULL
  #define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL

+#define APPLE_DART_PTE_PROT_NO_WRITE (1<<7)
+#define APPLE_DART_PTE_PROT_NO_READ (1<<8)
+
  /* IOPTE accessors */
  #define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
@@ -381,6 +384,15 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
  {
         arm_lpae_iopte pte;

+       if (data->iop.fmt == ARM_APPLE_DART) {
+               pte = 0;
+               if (!(prot & IOMMU_WRITE))
+                       pte |= APPLE_DART_PTE_PROT_NO_WRITE;
+               if (!(prot & IOMMU_READ))
+                       pte |= APPLE_DART_PTE_PROT_NO_READ;
+               return pte;
What about the other bits, such as sharability, XN, etc? Do they not 
exist on DART? Or have they not been reverse engineered and 0s happen to 
"just work"?
quoted hunk ↗ jump to hunk
+       }
+
         if (data->iop.fmt == ARM_64_LPAE_S1 ||
             data->iop.fmt == ARM_32_LPAE_S1) {
                 pte = ARM_LPAE_PTE_nG;
@@ -1043,6 +1055,51 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
         return NULL;
  }

+static struct io_pgtable *
+apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
+{
+       struct arm_lpae_io_pgtable *data;
+       int i;
+
+       if (cfg->oas > 36)
+               return NULL;
+
+       data = arm_lpae_alloc_pgtable(cfg);
+       if (!data)
+               return NULL;
+
+       /*
+        * Apple's DART always requires three levels with the first level being
+        * stored in four MMIO registers. We always concatenate the first and
+        * second level so that we only have to setup the MMIO registers once.
+        * This results in an effective two level pagetable.
+        */
+       if (data->start_level < 1)
+               return NULL;
+       if (data->start_level == 1 && data->pgd_bits > 2)
+               return NULL;
+       if (data->start_level > 1)
+               data->pgd_bits = 0;
+       data->start_level = 2;
+       cfg->apple_dart_cfg.n_ttbrs = 1 << data->pgd_bits;
Maybe add a BUG_ON if n_ttbrs > ARRAY_SIZE(ttbr)? Or alternatively, do a 
normal runtime check and bail out then.


Alex



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help