> + if (dev_is_pci(dev)) { > + /* VT-d supports devices with full 20 bit PASIDs only */ > + if (pci_max_pasids(to_pci_dev(dev)) != PASID_MAX) > + return -EINVAL; > + } else { > + return -ENOTSUPP; > + }
This looks strange. Why not: if (!dev_is_pci(dev)) { return -ENOTSUPP; /* VT-d supports devices with full 20 bit PASIDs only */ if (pci_max_pasids(to_pci_dev(dev)) != PASID_MAX) return -EINVAL; > + for_each_svm_dev(sdev, svm, dev) { > + /* > + * For devices with aux domains, we should allow > multiple > + * bind calls with the same PASID and pdev. > + */ > + if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)) > { > + sdev->users++; > + } else { > + dev_warn_ratelimited(dev, "Already bound with > PASID %u\n", > + svm->pasid); > + ret = -EBUSY; > + } > + goto out; Is this intentionally a for loop that jumps out of the loop after the first device? > + /* > + * PASID table is per device for better security. Therefore, for > + * each bind of a new device even with an existing PASID, we need to > + * call the nested mode setup function here. > + */ > + spin_lock(&iommu->lock); > + ret = intel_pasid_setup_nested(iommu, > + dev, > + (pgd_t *)data->gpgd, > + data->hpasid, > + &data->vtd, > + dmar_domain, > + data->addr_width); Why not: et = intel_pasid_setup_nested(iommu, dev, (pgd_t *)data->gpgd, data->hpasid, &data->vtd, dmar_domain, data->addr_width); ? > + for_each_svm_dev(sdev, svm, dev) { > + ret = 0; ... > + break; > + } Same only looks at the first device style. Why dos it only care about the first device? That needs at least a comment, and probably a first_svm_dev or so heper to make it explicit.