Message ID | 20220621071848.14834-5-j@jannau.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | iommu: M1 Pro/Max DART support | expand |
On 2022-06-21 08:18, Janne Grunau wrote: > From: Sven Peter <sven@svenpeter.dev> > > The DARTs present in the M1 Pro/Max/Ultra SoC use a diffent PTE format. > They support a 42bit physical address space by shifting the paddr and > extending its mask inside the PTE. > They also come with mandatory sub-page protection now which we just > configure to always allow access to the entire page. This feature is > already present but optional on the previous DARTs which allows to > unconditionally configure it. > > Signed-off-by: Sven Peter <sven@svenpeter.dev> > Co-developed-by: Janne Grunau <j@jannau.net> > Signed-off-by: Janne Grunau <j@jannau.net> > > --- > > Changes in v3: > - apply change to io-pgtable-dart.c > - handle pte <> paddr conversion based on the pte format instead of > the output address size > > Changes in v2: > - add APPLE_DART2 PTE format > > drivers/iommu/io-pgtable-dart.c | 51 +++++++++++++++++++++++++++------ > drivers/iommu/io-pgtable.c | 1 + > include/linux/io-pgtable.h | 1 + > 3 files changed, 45 insertions(+), 8 deletions(-) > [...] > @@ -536,7 +571,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) > if (!cfg->coherent_walk) > return NULL; > > - if (cfg->oas > 36) > + if (cfg->oas != 36 && cfg->oas != 42) > return NULL; Wouldn't it make sense to tie this to the format? Maybe 36-bit OAS is still valid with v2, but presumably 42-bit with v1 definitely isn't. Robin.
On 28/06/2022 00.13, Robin Murphy wrote: > On 2022-06-21 08:18, Janne Grunau wrote: >> From: Sven Peter <sven@svenpeter.dev> >> >> The DARTs present in the M1 Pro/Max/Ultra SoC use a diffent PTE format. >> They support a 42bit physical address space by shifting the paddr and >> extending its mask inside the PTE. >> They also come with mandatory sub-page protection now which we just >> configure to always allow access to the entire page. This feature is >> already present but optional on the previous DARTs which allows to >> unconditionally configure it. >> >> Signed-off-by: Sven Peter <sven@svenpeter.dev> >> Co-developed-by: Janne Grunau <j@jannau.net> >> Signed-off-by: Janne Grunau <j@jannau.net> >> >> --- >> >> Changes in v3: >> - apply change to io-pgtable-dart.c >> - handle pte <> paddr conversion based on the pte format instead of >> the output address size >> >> Changes in v2: >> - add APPLE_DART2 PTE format >> >> drivers/iommu/io-pgtable-dart.c | 51 +++++++++++++++++++++++++++------ >> drivers/iommu/io-pgtable.c | 1 + >> include/linux/io-pgtable.h | 1 + >> 3 files changed, 45 insertions(+), 8 deletions(-) >> > [...] >> @@ -536,7 +571,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) >> if (!cfg->coherent_walk) >> return NULL; >> >> - if (cfg->oas > 36) >> + if (cfg->oas != 36 && cfg->oas != 42) >> return NULL; > > Wouldn't it make sense to tie this to the format? Maybe 36-bit OAS is > still valid with v2, but presumably 42-bit with v1 definitely isn't. FWIW, 36-bit OAS with v2 is valid (this is the case on M2/t8112). - Hector
On 2022-06-27 16:13:20 +0100, Robin Murphy wrote: > On 2022-06-21 08:18, Janne Grunau wrote: > > From: Sven Peter <sven@svenpeter.dev> > > > > The DARTs present in the M1 Pro/Max/Ultra SoC use a diffent PTE format. > > They support a 42bit physical address space by shifting the paddr and > > extending its mask inside the PTE. > > They also come with mandatory sub-page protection now which we just > > configure to always allow access to the entire page. This feature is > > already present but optional on the previous DARTs which allows to > > unconditionally configure it. > > > > Signed-off-by: Sven Peter <sven@svenpeter.dev> > > Co-developed-by: Janne Grunau <j@jannau.net> > > Signed-off-by: Janne Grunau <j@jannau.net> > > > > --- > > > > Changes in v3: > > - apply change to io-pgtable-dart.c > > - handle pte <> paddr conversion based on the pte format instead of > > the output address size > > > > Changes in v2: > > - add APPLE_DART2 PTE format > > > > drivers/iommu/io-pgtable-dart.c | 51 +++++++++++++++++++++++++++------ > > drivers/iommu/io-pgtable.c | 1 + > > include/linux/io-pgtable.h | 1 + > > 3 files changed, 45 insertions(+), 8 deletions(-) > > > [...] > > @@ -536,7 +571,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) > > if (!cfg->coherent_walk) > > return NULL; > > - if (cfg->oas > 36) > > + if (cfg->oas != 36 && cfg->oas != 42) > > return NULL; > > Wouldn't it make sense to tie this to the format? Maybe 36-bit OAS is still > valid with v2, but presumably 42-bit with v1 definitely isn't. The format is not know inside the alloc call unless I add per format alloc wrapper. I think we can trust the caller for now. Janne
diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c index fa8025c03bb5..9c3c2505f3dc 100644 --- a/drivers/iommu/io-pgtable-dart.c +++ b/drivers/iommu/io-pgtable-dart.c @@ -68,12 +68,19 @@ #define APPLE_DART_PTE_SUBPAGE_END GENMASK_ULL(51, 40) #define APPLE_DART1_PADDR_MASK GENMASK_ULL(35, 12) +#define APPLE_DART2_PADDR_MASK GENMASK_ULL(37, 10) +#define APPLE_DART2_PADDR_SHIFT (4) /* Apple DART1 protection bits */ #define APPLE_DART1_PTE_PROT_NO_READ BIT(8) #define APPLE_DART1_PTE_PROT_NO_WRITE BIT(7) #define APPLE_DART1_PTE_PROT_SP_DIS BIT(1) +/* Apple DART2 protection bits */ +#define APPLE_DART2_PTE_PROT_NO_READ BIT(3) +#define APPLE_DART2_PTE_PROT_NO_WRITE BIT(2) +#define APPLE_DART2_PTE_PROT_NO_CACHE BIT(1) + /* marks PTE as valid */ #define APPLE_DART_PTE_VALID BIT(0) @@ -101,13 +108,31 @@ static inline bool iopte_leaf(dart_iopte pte, int lvl, static dart_iopte paddr_to_iopte(phys_addr_t paddr, struct dart_io_pgtable *data) { - return paddr & APPLE_DART1_PADDR_MASK; + dart_iopte pte; + + if (data->iop.fmt == APPLE_DART) + return paddr & APPLE_DART1_PADDR_MASK; + + /* format is APPLE_DART2 */ + pte = paddr >> APPLE_DART2_PADDR_SHIFT; + pte &= APPLE_DART2_PADDR_MASK; + + return pte; } static phys_addr_t iopte_to_paddr(dart_iopte pte, struct dart_io_pgtable *data) { - return pte & APPLE_DART1_PADDR_MASK; + u64 paddr; + + if (data->iop.fmt == APPLE_DART) + return pte & APPLE_DART1_PADDR_MASK; + + /* format is APPLE_DART2 */ + paddr = pte & APPLE_DART2_PADDR_MASK; + paddr <<= APPLE_DART2_PADDR_SHIFT; + + return paddr; } static void *__dart_alloc_pages(size_t size, gfp_t gfp, @@ -139,7 +164,7 @@ static void __dart_init_pte(struct dart_io_pgtable *data, size_t sz = DART_BLOCK_SIZE(lvl, data); int i; - if (lvl == DART_MAX_LEVELS - 1) + if (lvl == DART_MAX_LEVELS - 1 && data->iop.fmt == APPLE_DART) pte |= APPLE_DART1_PTE_PROT_SP_DIS; pte |= APPLE_DART_PTE_VALID; @@ -251,10 +276,20 @@ static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data, { dart_iopte pte = 0; - if (!(prot & IOMMU_WRITE)) - pte |= APPLE_DART1_PTE_PROT_NO_WRITE; - if (!(prot & IOMMU_READ)) - pte |= APPLE_DART1_PTE_PROT_NO_READ; + if (data->iop.fmt == APPLE_DART) { + if (!(prot & IOMMU_WRITE)) + pte |= APPLE_DART1_PTE_PROT_NO_WRITE; + if (!(prot & IOMMU_READ)) + pte |= APPLE_DART1_PTE_PROT_NO_READ; + } + if (data->iop.fmt == APPLE_DART2) { + if (!(prot & IOMMU_WRITE)) + pte |= APPLE_DART2_PTE_PROT_NO_WRITE; + if (!(prot & IOMMU_READ)) + pte |= APPLE_DART2_PTE_PROT_NO_READ; + if (!(prot & IOMMU_CACHE)) + pte |= APPLE_DART2_PTE_PROT_NO_CACHE; + } return pte; } @@ -536,7 +571,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) if (!cfg->coherent_walk) return NULL; - if (cfg->oas > 36) + if (cfg->oas != 36 && cfg->oas != 42) return NULL; data = dart_alloc_pgtable(cfg); diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c index e6edc6686859..a5d0f01afa7b 100644 --- a/drivers/iommu/io-pgtable.c +++ b/drivers/iommu/io-pgtable.c @@ -23,6 +23,7 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = { #endif #ifdef CONFIG_APPLE_DART [APPLE_DART] = &io_pgtable_apple_dart_init_fns, + [APPLE_DART2] = &io_pgtable_apple_dart_init_fns, #endif #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S [ARM_V7S] = &io_pgtable_arm_v7s_init_fns, diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 86af6f0a00a2..76b98511cbc8 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -17,6 +17,7 @@ enum io_pgtable_fmt { ARM_MALI_LPAE, AMD_IOMMU_V1, APPLE_DART, + APPLE_DART2, IO_PGTABLE_NUM_FMTS, };