Lines Matching +full:iommu +full:- +full:parent

1 // SPDX-License-Identifier: GPL-2.0
3 * nested.c - nested mode translation support
14 #include <linux/iommu.h>
16 #include <linux/pci-ats.h>
18 #include "iommu.h"
26 struct intel_iommu *iommu = info->iommu; in intel_nested_attach_dev() local
30 if (info->domain) in intel_nested_attach_dev()
33 if (iommu->agaw < dmar_domain->s2_domain->agaw) { in intel_nested_attach_dev()
35 return -ENODEV; in intel_nested_attach_dev()
39 * Stage-1 domain cannot work alone, it is nested on a s2_domain. in intel_nested_attach_dev()
41 * to ensure the s2_domain is compatible with this IOMMU. in intel_nested_attach_dev()
43 ret = paging_domain_compatible(&dmar_domain->s2_domain->domain, dev); in intel_nested_attach_dev()
49 ret = domain_attach_iommu(dmar_domain, iommu); in intel_nested_attach_dev()
51 dev_err_ratelimited(dev, "Failed to attach domain to iommu\n"); in intel_nested_attach_dev()
59 ret = intel_pasid_setup_nested(iommu, dev, in intel_nested_attach_dev()
64 info->domain = dmar_domain; in intel_nested_attach_dev()
65 spin_lock_irqsave(&dmar_domain->lock, flags); in intel_nested_attach_dev()
66 list_add(&info->link, &dmar_domain->devices); in intel_nested_attach_dev()
67 spin_unlock_irqrestore(&dmar_domain->lock, flags); in intel_nested_attach_dev()
73 domain_detach_iommu(dmar_domain, iommu); in intel_nested_attach_dev()
81 struct dmar_domain *s2_domain = dmar_domain->s2_domain; in intel_nested_domain_free()
83 spin_lock(&s2_domain->s1_lock); in intel_nested_domain_free()
84 list_del(&dmar_domain->s2_link); in intel_nested_domain_free()
85 spin_unlock(&s2_domain->s1_lock); in intel_nested_domain_free()
86 kfree(dmar_domain->qi_batch); in intel_nested_domain_free()
98 if (array->type != IOMMU_HWPT_INVALIDATE_DATA_VTD_S1) { in intel_nested_cache_invalidate_user()
99 ret = -EINVAL; in intel_nested_cache_invalidate_user()
103 for (index = 0; index < array->entry_num; index++) { in intel_nested_cache_invalidate_user()
112 ret = -EOPNOTSUPP; in intel_nested_cache_invalidate_user()
118 ret = -EINVAL; in intel_nested_cache_invalidate_user()
123 inv_entry.addr + nrpages_to_size(inv_entry.npages) - 1, in intel_nested_cache_invalidate_user()
129 array->entry_num = processed; in intel_nested_cache_invalidate_user()
133 static int domain_setup_nested(struct intel_iommu *iommu, in domain_setup_nested() argument
139 return intel_pasid_setup_nested(iommu, dev, pasid, domain); in domain_setup_nested()
140 return intel_pasid_replace_nested(iommu, dev, pasid, in domain_setup_nested()
141 iommu_domain_did(old, iommu), in domain_setup_nested()
151 struct intel_iommu *iommu = info->iommu; in intel_nested_set_dev_pasid() local
155 if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev)) in intel_nested_set_dev_pasid()
156 return -EOPNOTSUPP; in intel_nested_set_dev_pasid()
158 if (context_copied(iommu, info->bus, info->devfn)) in intel_nested_set_dev_pasid()
159 return -EBUSY; in intel_nested_set_dev_pasid()
161 ret = paging_domain_compatible(&dmar_domain->s2_domain->domain, dev); in intel_nested_set_dev_pasid()
169 ret = domain_setup_nested(iommu, dmar_domain, dev, pasid, old); in intel_nested_set_dev_pasid()
190 intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent, in intel_iommu_domain_alloc_nested() argument
195 struct dmar_domain *s2_domain = to_dmar_domain(parent); in intel_iommu_domain_alloc_nested()
196 struct intel_iommu *iommu = info->iommu; in intel_iommu_domain_alloc_nested() local
201 if (!nested_supported(iommu) || flags) in intel_iommu_domain_alloc_nested()
202 return ERR_PTR(-EOPNOTSUPP); in intel_iommu_domain_alloc_nested()
205 if (user_data->type != IOMMU_HWPT_DATA_VTD_S1) in intel_iommu_domain_alloc_nested()
206 return ERR_PTR(-EOPNOTSUPP); in intel_iommu_domain_alloc_nested()
207 if (parent->ops != intel_iommu_ops.default_domain_ops || in intel_iommu_domain_alloc_nested()
208 !s2_domain->nested_parent) in intel_iommu_domain_alloc_nested()
209 return ERR_PTR(-EINVAL); in intel_iommu_domain_alloc_nested()
218 return ERR_PTR(-ENOMEM); in intel_iommu_domain_alloc_nested()
220 domain->use_first_level = true; in intel_iommu_domain_alloc_nested()
221 domain->s2_domain = s2_domain; in intel_iommu_domain_alloc_nested()
222 domain->s1_cfg = vtd; in intel_iommu_domain_alloc_nested()
223 domain->domain.ops = &intel_nested_domain_ops; in intel_iommu_domain_alloc_nested()
224 domain->domain.type = IOMMU_DOMAIN_NESTED; in intel_iommu_domain_alloc_nested()
225 INIT_LIST_HEAD(&domain->devices); in intel_iommu_domain_alloc_nested()
226 INIT_LIST_HEAD(&domain->dev_pasids); in intel_iommu_domain_alloc_nested()
227 INIT_LIST_HEAD(&domain->cache_tags); in intel_iommu_domain_alloc_nested()
228 spin_lock_init(&domain->lock); in intel_iommu_domain_alloc_nested()
229 spin_lock_init(&domain->cache_lock); in intel_iommu_domain_alloc_nested()
230 xa_init(&domain->iommu_array); in intel_iommu_domain_alloc_nested()
232 spin_lock(&s2_domain->s1_lock); in intel_iommu_domain_alloc_nested()
233 list_add(&domain->s2_link, &s2_domain->s1_domains); in intel_iommu_domain_alloc_nested()
234 spin_unlock(&s2_domain->s1_lock); in intel_iommu_domain_alloc_nested()
236 return &domain->domain; in intel_iommu_domain_alloc_nested()