[PATCH 04/20] iommu/fsl_pamu: Replace set_platform_dma_ops() with IOMMU_DOMAIN_PLATFORM

Robin Murphy robin.murphy at arm.com
Wed May 3 03:57:59 PDT 2023


On 2023-05-01 19:02, Jason Gunthorpe wrote:
> It is not clear what this is actually doing, most likely this is IDENTITY
> behavior, but I think there is a chance it is BLOCKING given how the PAMU
> stuff is oddly used.

Logically it has to be identity, since there are no DMA ops interacting 
with this driver (it's not the TCE IOMMU of 
arch/powerpc/kernel/iommu.c), so any device using a kernel driver rather 
than VFIO must be using dma-direct and thus require an identity mapping.

At this point I finally got sufficiently fed up of this driver always 
being the mystery weirdo and tracked down an old QorIQ reference manual, 
and now I have about half an hours' worth of understanding of how the 
PAMU actually works.

Based on that, what setup_liodns() is doing is indeed setting up 
identity for everything initially. It also becomes apparent that it's 
never supported giving a PCI device back to its regular driver after 
using vfio-pci, since an attach/detach cycle will then leave the PPAACE 
invalid and thus DMA blocked. Oh well, that's been broken for 10 years; 
nobody cares. Call it an identity domain and move on.

Thanks,
Robin.

> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>   drivers/iommu/fsl_pamu_domain.c | 29 ++++++++++++++++++++++++++---
>   1 file changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
> index bce37229709965..4c65f1adfe7511 100644
> --- a/drivers/iommu/fsl_pamu_domain.c
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -283,15 +283,28 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain,
>   	return ret;
>   }
>   
> -static void fsl_pamu_set_platform_dma(struct device *dev)
> +/*
> + * FIXME: This seems to turn off the iommu HW but it is not obvious what state
> + * it leaves the HW in. This is probably really a BLOCKING or IDENTITY domain.
> + * For now this ensures that the old detach_dev behavior functions about the
> + * same as it always did, and we turn off the IOMMU whenever the UNMANAGED
> + * domain is detached.
> + */
> +static int fsl_pamu_platform_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 +325,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_platform_ops = {
> +	.attach_dev = fsl_pamu_platform_attach,
> +};
> +
> +static struct iommu_domain fsl_pamu_platform_domain = {
> +	.type = IOMMU_DOMAIN_PLATFORM,
> +	.ops = &fsl_pamu_platform_ops,
> +};
> +
>   /* Set the domain stash attribute */
>   int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu)
>   {
> @@ -448,11 +471,11 @@ static struct iommu_device *fsl_pamu_probe_device(struct device *dev)
>   }
>   
>   static const struct iommu_ops fsl_pamu_ops = {
> +	.default_domain = &fsl_pamu_platform_domain,
>   	.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,



More information about the linux-arm-kernel mailing list