iommu: Add MMIO mapping type
Subsystems (2)
Robin Murphy
reviewerPATCH 1/3 iommu: Add MMIO mapping type
On some platforms, MMIO regions might need slightly different treatment compared to mapping regular memory; add the notion of MMIO mappings to the IOMMU API's memory type flags, so that callers can let the IOMMU drivers know to do the right thing.
---
Hi all,
Since this is a prerequisite for both MSI remapping and slave DMA handling to function properly, and the latter still needs some design work to reach a consensus[1], I thought it worth reposting this separately from Niklas' series. I've also split it up now that there's short-descriptor format to cover as well.
Robin.
[1]:http://lists.linuxfoundation.org/pipermail/iommu/2016-March/016059.html
include/linux/iommu.h | 1 + 1 file changed, 1 insertion(+)
include/linux/iommu.h +1 -0
@@ -30,6 +30,7 @@#define IOMMU_WRITE (1 << 1)#define IOMMU_CACHE (1 << 2)/* DMA cache coherency */ #define IOMMU_NOEXEC (1 << 3) +#define IOMMU_MMIO (1 << 4)/* e.g. things like MSI doorbells */ struct iommu_ops ;struct iommu_group ;
Signature · 1 line
2.7.3.dirty
Robin Murphy
reviewerPATCH 2/3 iommu/io-pgtable-arm: Support IOMMU_MMIO flag
Teach the LPAE format to create Device mappings when asked.
--- drivers/iommu/io-pgtable-arm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/iommu/io-pgtable-arm.c +7 -2
@@ -355,7 +355,10 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,if (!(prot &IOMMU_WRITE ) && (prot &IOMMU_READ )) pte |=ARM_LPAE_PTE_AP_RDONLY ; -if (prot &IOMMU_CACHE ) +if (prot &IOMMU_MMIO ) + pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV + <<ARM_LPAE_PTE_ATTRINDX_SHIFT ); +else if (prot &IOMMU_CACHE ) pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE <<ARM_LPAE_PTE_ATTRINDX_SHIFT ); }else {
@@ -364,7 +367,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, pte |=ARM_LPAE_PTE_HAP_READ ;if (prot &IOMMU_WRITE ) pte |=ARM_LPAE_PTE_HAP_WRITE ; -if (prot &IOMMU_CACHE ) +if (prot &IOMMU_MMIO ) + pte |=ARM_LPAE_PTE_MEMATTR_DEV ; +else if (prot &IOMMU_CACHE ) pte |=ARM_LPAE_PTE_MEMATTR_OIWB ;else pte |=ARM_LPAE_PTE_MEMATTR_NC ;
Signature · 1 line
2.7.3.dirty
PATCH 2/3 iommu/io-pgtable-arm: Support IOMMU_MMIO flag
Hi Robin,
Quoted 3 lines · Robin Murphy
Teach the LPAE format to create Device mappings when asked.
Signed-off-by Robin Murphy <[email protected]>
don't know if it helps in any way but I tested that with my KVM PCIe/MSI passthrough series for mapping the GICv2m doorbell.
Best Regards
Eric
Quoted 32 lines
--- drivers/iommu/io-pgtable-arm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/iommu/io-pgtable-arm.c +7
-2@@ -355,7 +355,10 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,if (!(prot &IOMMU_WRITE ) && (prot &IOMMU_READ )) pte |=ARM_LPAE_PTE_AP_RDONLY ; -if (prot &IOMMU_CACHE ) +if (prot &IOMMU_MMIO ) + pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV + <<ARM_LPAE_PTE_ATTRINDX_SHIFT ); +else if (prot &IOMMU_CACHE ) pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE <<ARM_LPAE_PTE_ATTRINDX_SHIFT ); }else {@@ -364,7 +367,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, pte |=ARM_LPAE_PTE_HAP_READ ;if (prot &IOMMU_WRITE ) pte |=ARM_LPAE_PTE_HAP_WRITE ; -if (prot &IOMMU_CACHE ) +if (prot &IOMMU_MMIO ) + pte |=ARM_LPAE_PTE_MEMATTR_DEV ; +else if (prot &IOMMU_CACHE ) pte |=ARM_LPAE_PTE_MEMATTR_OIWB ;else pte |=ARM_LPAE_PTE_MEMATTR_NC ;
Robin Murphy
reviewerPATCH 3/3 iommu/io-pgtable-arm-v7s: Support IOMMU_MMIO flag
In reply to Robin MurphyTeach the short-descriptor format to create Device mappings when asked.
--- drivers/iommu/io-pgtable-arm-v7s.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/iommu/io-pgtable-arm-v7s.c +11 -5
@@ -258,9 +258,10 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl, struct io_pgtable_cfg *cfg) {bool ap = !(cfg->quirks &IO_PGTABLE_QUIRK_NO_PERMS ); -arm_v7s_iopte pte =ARM_V7S_ATTR_NG |ARM_V7S_ATTR_S | -ARM_V7S_ATTR_TEX (1 ); +arm_v7s_iopte pte =ARM_V7S_ATTR_NG |ARM_V7S_ATTR_S ; +if (!(prot &IOMMU_MMIO )) + pte |=ARM_V7S_ATTR_TEX (1 );if (ap) { pte |=ARM_V7S_PTE_AF |ARM_V7S_PTE_AP_UNPRIV ;if (!(prot &IOMMU_WRITE ))
@@ -270,7 +271,9 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,if ((prot &IOMMU_NOEXEC ) && ap) pte |=ARM_V7S_ATTR_XN (lvl); -if (prot &IOMMU_CACHE ) +if (prot &IOMMU_MMIO ) + pte |=ARM_V7S_ATTR_B ; +else if (prot &IOMMU_CACHE ) pte |=ARM_V7S_ATTR_B |ARM_V7S_ATTR_C ;return pte;
@@ -279,10 +282,13 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,static int arm_v7s_pte_to_prot (arm_v7s_iopte pte,int lvl) {int prot =IOMMU_READ ; +arm_v7s_iopte attr = pte >>ARM_V7S_ATTR_SHIFT (lvl); -if (pte & (ARM_V7S_PTE_AP_RDONLY <<ARM_V7S_ATTR_SHIFT (lvl))) +if (attr &ARM_V7S_PTE_AP_RDONLY ) prot |=IOMMU_WRITE ; -if (pte &ARM_V7S_ATTR_C ) +if ((attr & (ARM_V7S_TEX_MASK <<ARM_V7S_TEX_SHIFT )) ==0 ) + prot |=IOMMU_MMIO ; +else if (pte &ARM_V7S_ATTR_C ) prot |=IOMMU_CACHE ;return prot;
Signature · 1 line
2.7.3.dirty
PATCH 1/3 iommu: Add MMIO mapping type
In reply to Robin MurphyQuoted 6 lines · Robin Murphy
On some platforms, MMIO regions might need slightly different treatment compared to mapping regular memory; add the notion of MMIO mappings to the IOMMU API's memory type flags, so that callers can let the IOMMU drivers know to do the right thing.
Signed-off-by Robin Murphy <[email protected]>
Applied the series, thanks.