Re: [PATCH v2 09/25] iommu/fsl_pamu: Implement an IDENTITY domain

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023-05-16 01:00, Jason Gunthorpe wrote:
Robin was able to check the documentation and what fsl_pamu has
historically called detach_dev() is really putting the IOMMU into an
IDENTITY mode.

Unfortunately it was the other way around - it's the call to fsl_setup_liodns() from fsl_pamu_probe() which leaves everything in bypass by default (the PAACE_ATM_NO_XLATE part, IIRC), whereas the detach_device() call here ends up disabling the given device's LIODN altogether. There doesn't appear to have ever been any code anywhere for putting things *back* into bypass after using a VFIO domain, so as-is these default domains would probably break all DMA :(

Thanks,
Robin.

Move to the new core support for ARM_DMA_USE_IOMMU by defining
ops->identity_domain. This is a ppc driver without any dma_ops, so ensure
the identity translation is the default domain.

Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
---
  drivers/iommu/fsl_pamu_domain.c | 32 +++++++++++++++++++++++++++++---
  1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index bce37229709965..ca4f5ebf028783 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -283,15 +283,21 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain,
  	return ret;
  }
-static void fsl_pamu_set_platform_dma(struct device *dev)
+static int fsl_pamu_identity_attach(struct iommu_domain *platform_domain,
+				    struct device *dev)
  {
  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
+	struct fsl_dma_domain *dma_domain;
  	const u32 *prop;
  	int len;
  	struct pci_dev *pdev = NULL;
  	struct pci_controller *pci_ctl;
+ if (domain == platform_domain || !domain)
+		return 0;
+
+	dma_domain = to_fsl_dma_domain(domain);
+
  	/*
  	 * Use LIODN of the PCI controller while detaching a
  	 * PCI device.
@@ -312,8 +318,18 @@ static void fsl_pamu_set_platform_dma(struct device *dev)
  		detach_device(dev, dma_domain);
  	else
  		pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);
+	return 0;
  }
+static struct iommu_domain_ops fsl_pamu_identity_ops = {
+	.attach_dev = fsl_pamu_identity_attach,
+};
+
+static struct iommu_domain fsl_pamu_identity_domain = {
+	.type = IOMMU_DOMAIN_IDENTITY,
+	.ops = &fsl_pamu_identity_ops,
+};
+
  /* Set the domain stash attribute */
  int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu)
  {
@@ -447,12 +463,22 @@ static struct iommu_device *fsl_pamu_probe_device(struct device *dev)
  	return &pamu_iommu;
  }
+static int fsl_pamu_def_domain_type(struct device *dev)
+{
+	/*
+	 * This platform does not use dma_ops at all so the normally the iommu
+	 * must be in identity mode
+	 */
+	return IOMMU_DOMAIN_IDENTITY;
+}
+
  static const struct iommu_ops fsl_pamu_ops = {
+	.identity_domain = &fsl_pamu_identity_domain,
+	.def_domain_type = &fsl_pamu_def_domain_type,
  	.capable	= fsl_pamu_capable,
  	.domain_alloc	= fsl_pamu_domain_alloc,
  	.probe_device	= fsl_pamu_probe_device,
  	.device_group   = fsl_pamu_device_group,
-	.set_platform_dma_ops = fsl_pamu_set_platform_dma,
  	.default_domain_ops = &(const struct iommu_domain_ops) {
  		.attach_dev	= fsl_pamu_attach_device,
  		.iova_to_phys	= fsl_pamu_iova_to_phys,



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux