Skip to content

Commit 67f6f56

Browse files
yiliu1765joergroedel
authored andcommitted
iommu/vt-d: Add set_dev_pasid callback for nested domain
Add intel_nested_set_dev_pasid() to set a nested type domain to a PASID of a device. Co-developed-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20241107122234.7424-12-yi.l.liu@intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 9bc18d2 commit 67f6f56

File tree

3 files changed

+57
-6
lines changed

3 files changed

+57
-6
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,12 +1812,6 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
18121812
(pgd_t *)pgd, flags, old);
18131813
}
18141814

1815-
static bool dev_is_real_dma_subdevice(struct device *dev)
1816-
{
1817-
return dev && dev_is_pci(dev) &&
1818-
pci_real_dma_dev(to_pci_dev(dev)) != to_pci_dev(dev);
1819-
}
1820-
18211815
static int dmar_domain_attach_device(struct dmar_domain *domain,
18221816
struct device *dev)
18231817
{

drivers/iommu/intel/iommu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/bitfield.h>
2323
#include <linux/xarray.h>
2424
#include <linux/perf_event.h>
25+
#include <linux/pci.h>
2526

2627
#include <asm/cacheflush.h>
2728
#include <asm/iommu.h>
@@ -832,6 +833,12 @@ iommu_domain_did(struct iommu_domain *domain, struct intel_iommu *iommu)
832833
return domain_id_iommu(to_dmar_domain(domain), iommu);
833834
}
834835

836+
static inline bool dev_is_real_dma_subdevice(struct device *dev)
837+
{
838+
return dev && dev_is_pci(dev) &&
839+
pci_real_dma_dev(to_pci_dev(dev)) != to_pci_dev(dev);
840+
}
841+
835842
/*
836843
* 0: readable
837844
* 1: writable

drivers/iommu/intel/nested.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,58 @@ static int intel_nested_cache_invalidate_user(struct iommu_domain *domain,
130130
return ret;
131131
}
132132

133+
static int domain_setup_nested(struct intel_iommu *iommu,
134+
struct dmar_domain *domain,
135+
struct device *dev, ioasid_t pasid,
136+
struct iommu_domain *old)
137+
{
138+
if (!old)
139+
return intel_pasid_setup_nested(iommu, dev, pasid, domain);
140+
return intel_pasid_replace_nested(iommu, dev, pasid,
141+
iommu_domain_did(old, iommu),
142+
domain);
143+
}
144+
145+
static int intel_nested_set_dev_pasid(struct iommu_domain *domain,
146+
struct device *dev, ioasid_t pasid,
147+
struct iommu_domain *old)
148+
{
149+
struct device_domain_info *info = dev_iommu_priv_get(dev);
150+
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
151+
struct intel_iommu *iommu = info->iommu;
152+
struct dev_pasid_info *dev_pasid;
153+
int ret;
154+
155+
if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev))
156+
return -EOPNOTSUPP;
157+
158+
if (context_copied(iommu, info->bus, info->devfn))
159+
return -EBUSY;
160+
161+
ret = paging_domain_compatible(&dmar_domain->s2_domain->domain, dev);
162+
if (ret)
163+
return ret;
164+
165+
dev_pasid = domain_add_dev_pasid(domain, dev, pasid);
166+
if (IS_ERR(dev_pasid))
167+
return PTR_ERR(dev_pasid);
168+
169+
ret = domain_setup_nested(iommu, dmar_domain, dev, pasid, old);
170+
if (ret)
171+
goto out_remove_dev_pasid;
172+
173+
domain_remove_dev_pasid(old, dev, pasid);
174+
175+
return 0;
176+
177+
out_remove_dev_pasid:
178+
domain_remove_dev_pasid(domain, dev, pasid);
179+
return ret;
180+
}
181+
133182
static const struct iommu_domain_ops intel_nested_domain_ops = {
134183
.attach_dev = intel_nested_attach_dev,
184+
.set_dev_pasid = intel_nested_set_dev_pasid,
135185
.free = intel_nested_domain_free,
136186
.cache_invalidate_user = intel_nested_cache_invalidate_user,
137187
};

0 commit comments

Comments
 (0)