+{No callback to the driver?
+ struct iommu_sva_domain *sva_domain;
+ struct iommu_domain *domain;
+
+ if (!bus->iommu_ops || !bus->iommu_ops->sva_domain_ops)
+ return ERR_PTR(-ENODEV);
+
+ sva_domain = kzalloc(sizeof(*sva_domain), GFP_KERNEL);
+ if (!sva_domain)
+ return ERR_PTR(-ENOMEM);
+
+ mmgrab(mm);
+ sva_domain->mm = mm;
+
+ domain = &sva_domain->domain;
+ domain->type = IOMMU_DOMAIN_SVA;
+ domain->ops = bus->iommu_ops->sva_domain_ops;
+
+ return domain;
+}
+
+void iommu_sva_free_domain(struct iommu_domain *domain)
+{
+ struct iommu_sva_domain *sva_domain = to_sva_domain(domain);
+
+ mmdrop(sva_domain->mm);
+ kfree(sva_domain);
+}
+int iommu_sva_set_domain(struct iommu_domain *domain, struct device *dev,Why does this function exist? Just call iommu_set_device_pasid()
+ ioasid_t pasid)
+{
+int iommu_set_device_pasid(struct iommu_domain *domain, struct device *dev,Here you can continue to use attach/detach language as at this API
+ ioasid_t pasid)
+{
level we expect strict pairing..
+void iommu_block_device_pasid(struct iommu_domain *domain, struct device *dev,Should be the blocking domain.
+ ioasid_t pasid)
+{
+ struct iommu_group *group = iommu_group_get(dev);
+
+ mutex_lock(&group->mutex);
+ domain->ops->block_dev_pasid(domain, dev, pasid);
+ xa_erase(&group->pasid_array, pasid);
+ mutex_unlock(&group->mutex);