Skip to content

Commit

Permalink
iommu/io-pgtable: Move Apple DART support to its own file
Browse files Browse the repository at this point in the history
The pte format used by the DARTs found in the Apple M1 (t8103) is not
fully compatible with io-pgtable-arm. The 24 MSB are used for subpage
protection (mapping only parts of page) and conflict with the address
mask. In addition bit 1 is not available for tagging entries but disables
subpage protection. Subpage protection could be useful to support a CPU
granule of 4k with the fixed IOMMU page size of 16k.

The DARTs found on Apple M1 Pro/Max/Ultra use another different pte
format which is even less compatible. To support an output address size
of 42 bit the address is shifted down by 4. Subpage protection is
mandatory and bit 1 signifies uncached mappings used by the display
controller.

It would be advantageous to share code for all known Apple DART
variants to support common features. The page table allocator for DARTs
is less complex since it uses a two levels of translation table without
support for huge pages.

Signed-off-by: Janne Grunau <j@jannau.net>
Acked-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Sven Peter <sven@svenpeter.dev>
Acked-by: Hector Martin <marcan@marcan.st>
Link: https://lore.kernel.org/r/20220916094152.87137-3-j@jannau.net
[ joro: Fix compile warning in __dart_alloc_pages()]
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Janne Grunau authored and Joerg Roedel committed Sep 26, 2022
1 parent 7e18e42 commit 745ef10
Show file tree
Hide file tree
Showing 6 changed files with 442 additions and 64 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1887,6 +1887,7 @@ F: drivers/dma/apple-admac.c
F: drivers/i2c/busses/i2c-pasemi-core.c
F: drivers/i2c/busses/i2c-pasemi-platform.c
F: drivers/iommu/apple-dart.c
F: drivers/iommu/io-pgtable-dart.c
F: drivers/irqchip/irq-apple-aic.c
F: drivers/mailbox/apple-mailbox.c
F: drivers/nvme/host/apple.c
Expand Down
13 changes: 12 additions & 1 deletion drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST

If unsure, say N here.

config IOMMU_IO_PGTABLE_DART
bool "Apple DART Formats"
select IOMMU_IO_PGTABLE
depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
help
Enable support for the Apple DART pagetable formats. These include
the t8020 and t6000/t8110 DART formats used in Apple M1/M2 family
SoCs.

If unsure, say N here.

endmenu

config IOMMU_DEBUGFS
Expand Down Expand Up @@ -294,7 +305,7 @@ config APPLE_DART
tristate "Apple DART IOMMU Support"
depends on ARCH_APPLE || (COMPILE_TEST && !GENERIC_ATOMIC64)
select IOMMU_API
select IOMMU_IO_PGTABLE_LPAE
select IOMMU_IO_PGTABLE_DART
default ARCH_APPLE
help
Support for Apple DART (Device Address Resolution Table) IOMMUs
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) += io-pgtable-dart.o
obj-$(CONFIG_IOASID) += ioasid.o
obj-$(CONFIG_IOMMU_IOVA) += iova.o
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
Expand Down
63 changes: 0 additions & 63 deletions drivers/iommu/io-pgtable-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,6 @@
#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))

Expand Down Expand Up @@ -406,15 +403,6 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
{
arm_lpae_iopte pte;

if (data->iop.fmt == 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;
}

if (data->iop.fmt == ARM_64_LPAE_S1 ||
data->iop.fmt == ARM_32_LPAE_S1) {
pte = ARM_LPAE_PTE_nG;
Expand Down Expand Up @@ -1107,52 +1095,6 @@ 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;

/*
* The table format itself always uses two levels, but the total VA
* space is mapped by four separate tables, making the MMIO registers
* an effective "level 1". For simplicity, though, we treat this
* equivalently to LPAE stage 2 concatenation at level 2, with the
* additional TTBRs each just pointing at consecutive pages.
*/
if (data->start_level < 1)
goto out_free_data;
if (data->start_level == 1 && data->pgd_bits > 2)
goto out_free_data;
if (data->start_level > 1)
data->pgd_bits = 0;
data->start_level = 2;
cfg->apple_dart_cfg.n_ttbrs = 1 << data->pgd_bits;
data->pgd_bits += data->bits_per_level;

data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data), GFP_KERNEL,
cfg);
if (!data->pgd)
goto out_free_data;

for (i = 0; i < cfg->apple_dart_cfg.n_ttbrs; ++i)
cfg->apple_dart_cfg.ttbr[i] =
virt_to_phys(data->pgd + i * ARM_LPAE_GRANULE(data));

return &data->iop;

out_free_data:
kfree(data);
return NULL;
}

struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
.alloc = arm_64_lpae_alloc_pgtable_s1,
.free = arm_lpae_free_pgtable,
Expand All @@ -1178,11 +1120,6 @@ struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = {
.free = arm_lpae_free_pgtable,
};

struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns = {
.alloc = apple_dart_alloc_pgtable,
.free = arm_lpae_free_pgtable,
};

#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST

static struct io_pgtable_cfg *cfg_cookie __initdata;
Expand Down
Loading

0 comments on commit 745ef10

Please sign in to comment.