On Sun, Nov 26, 2023 at 10:34:28PM -0800, Yi Liu wrote: > +static int intel_nested_set_dev_pasid(struct iommu_domain *domain, > + struct device *dev, ioasid_t pasid) > +{ > + struct device_domain_info *info = dev_iommu_priv_get(dev); > + struct dmar_domain *dmar_domain = to_dmar_domain(domain); > + struct intel_iommu *iommu = info->iommu; > + struct dev_pasid_info *dev_pasid; > + unsigned long flags; > + int ret = 0; > + > + if (!pasid_supported(iommu)) > + return -EOPNOTSUPP; > + > + if (iommu->agaw < dmar_domain->s2_domain->agaw) > + return -EINVAL; > + > + ret = prepare_domain_attach_device(&dmar_domain->s2_domain->domain, dev); > + if (ret) > + return ret; > + > + dev_pasid = kzalloc(sizeof(*dev_pasid), GFP_KERNEL); > + if (!dev_pasid) > + return -ENOMEM; > + > + ret = domain_attach_iommu(dmar_domain, iommu); > + if (ret) > + goto err_free; > + > + ret = intel_pasid_setup_nested(iommu, dev, pasid, dmar_domain); > + if (ret) > + goto err_detach_iommu; > + > + dev_pasid->dev = dev; > + dev_pasid->pasid = pasid; > + spin_lock_irqsave(&dmar_domain->lock, flags); > + list_add(&dev_pasid->link_domain, &dmar_domain->dev_pasids); > + spin_unlock_irqrestore(&dmar_domain->lock, flags); > + > + return 0; > +err_detach_iommu: > + domain_detach_iommu(dmar_domain, iommu); > +err_free: > + kfree(dev_pasid); > + return ret; > +} This seems alot longer than I'd think it should be, why isn't it exactly the same code as the other set_dev_pasid's? Jason