Re: [PATCH v2 3/5] iommu: Add verisilicon IOMMU driver
From: Jason Gunthorpe <jgg@ziepe.ca>
Date: 2025-06-18 14:57:28
Also in:
linux-devicetree, linux-iommu, linux-rockchip, lkml
On Wed, Jun 18, 2025 at 04:09:12PM +0200, Benjamin Gaignard wrote:
+config VSI_IOMMU + bool "Verisilicon IOMMU Support" + depends on ARM64 + select IOMMU_API + select ARM_DMA_USE_IOMMU
ARM_DMA_USE_IOMMU is only used by ARM32, you don't need it if you depends on ARM64
+static void vsi_iommu_release_device(struct device *dev)
+{
+ struct vsi_iommu *iommu = dev_iommu_priv_get(dev);
+
+ device_link_remove(dev, iommu->dev);
+}This does not seem right, release is supposed to reprogram the HW to stop walking any page table. You should implement a static blocked (or identity?) domain that idles the hardware and use that as the blocked and release_domain in the ops. The logic around vsi_iommu_detach_device() and vsi_iommu_attach_device() is also not quite right. The attach can happen while iommu->domain is already set and doesn't deal with removing the iommu from the old domain's list. I would probably change vsi_iommu_enable() into vsi_iommu_set_paging() and then presumably vsi_iommu_disable() is vsi_iommu_set_blocking() ? vsi_iommu_detach_device() should be deleted and integrated into the blocked domain and attach error unwind.
+static int vsi_iommu_of_xlate(struct device *dev,
+ const struct of_phandle_args *args)
+{
+ struct platform_device *iommu_dev;
+
+ if (!dev_iommu_priv_get(dev)) {
+ iommu_dev = of_find_device_by_node(args->np);
+ if (WARN_ON(!iommu_dev))
+ return -EINVAL;
+
+ dev_iommu_priv_set(dev, platform_get_drvdata(iommu_dev));
+ }The driver should ideally not be calling dev_iommu_priv_set/get here, and this leads the reference doesn't it? Do what ARM did to locate the iommu_dev. I would also add a comment here:
+static int vsi_iommu_map(struct iommu_domain *domain, unsigned long _iova,
+ phys_addr_t paddr, size_t size, size_t count,
+ int prot, gfp_t gfp, size_t *mapped)
+{
+ struct vsi_iommu_domain *vsi_domain = to_vsi_domain(domain);
+ unsigned long flags;
+ dma_addr_t pte_dma, iova = (dma_addr_t)_iova;
+ u32 *page_table, *pte_addr;
+ u32 dte, pte_index;
+ int ret;/* * IOMMU drivers are not supposed to lock the page table, however this * driver does not safely handle the cache flushing or table * installation across concurrent threads so locking is used as a simple * solution. */
+ spin_lock_irqsave(&vsi_domain->dt_lock, flags);
Jason