Skip to content

Commit 586081d

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Remove DEFER_DEVICE_DOMAIN_INFO
Allocate and set the per-device iommu private data during iommu device probe. This makes the per-device iommu private data always available during iommu_probe_device() and iommu_release_device(). With this changed, the dummy DEFER_DEVICE_DOMAIN_INFO pointer could be removed. The wrappers for getting the private data and domain are also cleaned. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/20220214025704.3184654-1-baolu.lu@linux.intel.com Link: https://lore.kernel.org/r/20220301020159.633356-6-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent ee2653b commit 586081d

5 files changed

Lines changed: 79 additions & 130 deletions

File tree

drivers/iommu/intel/debugfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,8 @@ static void pgtable_walk_level(struct seq_file *m, struct dma_pte *pde,
344344

345345
static int show_device_domain_translation(struct device *dev, void *data)
346346
{
347-
struct dmar_domain *domain = find_domain(dev);
347+
struct device_domain_info *info = dev_iommu_priv_get(dev);
348+
struct dmar_domain *domain = info->domain;
348349
struct seq_file *m = data;
349350
u64 path[6] = { 0 };
350351

drivers/iommu/intel/iommu.c

Lines changed: 68 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -342,21 +342,6 @@ static int iommu_skip_te_disable;
342342
int intel_iommu_gfx_mapped;
343343
EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
344344

345-
#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
346-
struct device_domain_info *get_domain_info(struct device *dev)
347-
{
348-
struct device_domain_info *info;
349-
350-
if (!dev)
351-
return NULL;
352-
353-
info = dev_iommu_priv_get(dev);
354-
if (unlikely(info == DEFER_DEVICE_DOMAIN_INFO))
355-
return NULL;
356-
357-
return info;
358-
}
359-
360345
DEFINE_SPINLOCK(device_domain_lock);
361346
static LIST_HEAD(device_domain_list);
362347

@@ -741,11 +726,6 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
741726
return &context[devfn];
742727
}
743728

744-
static bool attach_deferred(struct device *dev)
745-
{
746-
return dev_iommu_priv_get(dev) == DEFER_DEVICE_DOMAIN_INFO;
747-
}
748-
749729
/**
750730
* is_downstream_to_pci_bridge - test if a device belongs to the PCI
751731
* sub-hierarchy of a candidate PCI-PCI bridge
@@ -2432,15 +2412,6 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
24322412
__iommu_flush_dev_iotlb(info, 0, MAX_AGAW_PFN_WIDTH);
24332413
}
24342414

2435-
static inline void unlink_domain_info(struct device_domain_info *info)
2436-
{
2437-
assert_spin_locked(&device_domain_lock);
2438-
list_del(&info->link);
2439-
list_del(&info->global);
2440-
if (info->dev)
2441-
dev_iommu_priv_set(info->dev, NULL);
2442-
}
2443-
24442415
static void domain_remove_dev_info(struct dmar_domain *domain)
24452416
{
24462417
struct device_domain_info *info, *tmp;
@@ -2452,24 +2423,6 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
24522423
spin_unlock_irqrestore(&device_domain_lock, flags);
24532424
}
24542425

2455-
struct dmar_domain *find_domain(struct device *dev)
2456-
{
2457-
struct device_domain_info *info;
2458-
2459-
if (unlikely(!dev || !dev->iommu))
2460-
return NULL;
2461-
2462-
if (unlikely(attach_deferred(dev)))
2463-
return NULL;
2464-
2465-
/* No lock here, assumes no domain exit in normal case */
2466-
info = get_domain_info(dev);
2467-
if (likely(info))
2468-
return info->domain;
2469-
2470-
return NULL;
2471-
}
2472-
24732426
static inline struct device_domain_info *
24742427
dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
24752428
{
@@ -2530,66 +2483,20 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
25302483
struct device *dev,
25312484
struct dmar_domain *domain)
25322485
{
2533-
struct device_domain_info *info;
2486+
struct device_domain_info *info = dev_iommu_priv_get(dev);
25342487
unsigned long flags;
25352488
int ret;
25362489

2537-
info = kzalloc(sizeof(*info), GFP_KERNEL);
2538-
if (!info)
2539-
return NULL;
2540-
2541-
if (!dev_is_real_dma_subdevice(dev)) {
2542-
info->bus = bus;
2543-
info->devfn = devfn;
2544-
info->segment = iommu->segment;
2545-
} else {
2546-
struct pci_dev *pdev = to_pci_dev(dev);
2547-
2548-
info->bus = pdev->bus->number;
2549-
info->devfn = pdev->devfn;
2550-
info->segment = pci_domain_nr(pdev->bus);
2551-
}
2552-
2553-
info->dev = dev;
2554-
info->domain = domain;
2555-
info->iommu = iommu;
2556-
2557-
if (dev && dev_is_pci(dev)) {
2558-
struct pci_dev *pdev = to_pci_dev(info->dev);
2559-
2560-
if (ecap_dev_iotlb_support(iommu->ecap) &&
2561-
pci_ats_supported(pdev) &&
2562-
dmar_find_matched_atsr_unit(pdev))
2563-
info->ats_supported = 1;
2564-
2565-
if (sm_supported(iommu)) {
2566-
if (pasid_supported(iommu)) {
2567-
int features = pci_pasid_features(pdev);
2568-
if (features >= 0)
2569-
info->pasid_supported = features | 1;
2570-
}
2571-
2572-
if (info->ats_supported && ecap_prs(iommu->ecap) &&
2573-
pci_pri_supported(pdev))
2574-
info->pri_supported = 1;
2575-
}
2576-
}
2577-
25782490
spin_lock_irqsave(&device_domain_lock, flags);
2491+
info->domain = domain;
25792492
spin_lock(&iommu->lock);
25802493
ret = domain_attach_iommu(domain, iommu);
25812494
spin_unlock(&iommu->lock);
2582-
25832495
if (ret) {
25842496
spin_unlock_irqrestore(&device_domain_lock, flags);
2585-
kfree(info);
25862497
return NULL;
25872498
}
2588-
25892499
list_add(&info->link, &domain->devices);
2590-
list_add(&info->global, &device_domain_list);
2591-
if (dev)
2592-
dev_iommu_priv_set(dev, info);
25932500
spin_unlock_irqrestore(&device_domain_lock, flags);
25942501

25952502
/* PASID table is mandatory for a PCI device in scalable mode. */
@@ -4336,13 +4243,11 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
43364243
intel_pasid_free_table(info->dev);
43374244
}
43384245

4339-
unlink_domain_info(info);
4246+
list_del(&info->link);
43404247

43414248
spin_lock_irqsave(&iommu->lock, flags);
43424249
domain_detach_iommu(domain, iommu);
43434250
spin_unlock_irqrestore(&iommu->lock, flags);
4344-
4345-
kfree(info);
43464251
}
43474252

43484253
static void dmar_remove_one_dev_info(struct device *dev)
@@ -4351,7 +4256,7 @@ static void dmar_remove_one_dev_info(struct device *dev)
43514256
unsigned long flags;
43524257

43534258
spin_lock_irqsave(&device_domain_lock, flags);
4354-
info = get_domain_info(dev);
4259+
info = dev_iommu_priv_get(dev);
43554260
if (info)
43564261
__dmar_remove_one_dev_info(info);
43574262
spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -4475,10 +4380,9 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
44754380

44764381
/* normally dev is not mapped */
44774382
if (unlikely(domain_context_mapped(dev))) {
4478-
struct dmar_domain *old_domain;
4383+
struct device_domain_info *info = dev_iommu_priv_get(dev);
44794384

4480-
old_domain = find_domain(dev);
4481-
if (old_domain)
4385+
if (info->domain)
44824386
dmar_remove_one_dev_info(dev);
44834387
}
44844388

@@ -4642,28 +4546,73 @@ static bool intel_iommu_capable(enum iommu_cap cap)
46424546

46434547
static struct iommu_device *intel_iommu_probe_device(struct device *dev)
46444548
{
4549+
struct pci_dev *pdev = dev_is_pci(dev) ? to_pci_dev(dev) : NULL;
4550+
struct device_domain_info *info;
46454551
struct intel_iommu *iommu;
4552+
unsigned long flags;
4553+
u8 bus, devfn;
46464554

4647-
iommu = device_to_iommu(dev, NULL, NULL);
4555+
iommu = device_to_iommu(dev, &bus, &devfn);
46484556
if (!iommu)
46494557
return ERR_PTR(-ENODEV);
46504558

4651-
if (translation_pre_enabled(iommu))
4652-
dev_iommu_priv_set(dev, DEFER_DEVICE_DOMAIN_INFO);
4559+
info = kzalloc(sizeof(*info), GFP_KERNEL);
4560+
if (!info)
4561+
return ERR_PTR(-ENOMEM);
4562+
4563+
if (dev_is_real_dma_subdevice(dev)) {
4564+
info->bus = pdev->bus->number;
4565+
info->devfn = pdev->devfn;
4566+
info->segment = pci_domain_nr(pdev->bus);
4567+
} else {
4568+
info->bus = bus;
4569+
info->devfn = devfn;
4570+
info->segment = iommu->segment;
4571+
}
4572+
4573+
info->dev = dev;
4574+
info->iommu = iommu;
4575+
if (dev_is_pci(dev)) {
4576+
if (ecap_dev_iotlb_support(iommu->ecap) &&
4577+
pci_ats_supported(pdev) &&
4578+
dmar_find_matched_atsr_unit(pdev))
4579+
info->ats_supported = 1;
4580+
4581+
if (sm_supported(iommu)) {
4582+
if (pasid_supported(iommu)) {
4583+
int features = pci_pasid_features(pdev);
4584+
4585+
if (features >= 0)
4586+
info->pasid_supported = features | 1;
4587+
}
4588+
4589+
if (info->ats_supported && ecap_prs(iommu->ecap) &&
4590+
pci_pri_supported(pdev))
4591+
info->pri_supported = 1;
4592+
}
4593+
}
4594+
4595+
spin_lock_irqsave(&device_domain_lock, flags);
4596+
list_add(&info->global, &device_domain_list);
4597+
dev_iommu_priv_set(dev, info);
4598+
spin_unlock_irqrestore(&device_domain_lock, flags);
46534599

46544600
return &iommu->iommu;
46554601
}
46564602

46574603
static void intel_iommu_release_device(struct device *dev)
46584604
{
4659-
struct intel_iommu *iommu;
4660-
4661-
iommu = device_to_iommu(dev, NULL, NULL);
4662-
if (!iommu)
4663-
return;
4605+
struct device_domain_info *info = dev_iommu_priv_get(dev);
4606+
unsigned long flags;
46644607

46654608
dmar_remove_one_dev_info(dev);
46664609

4610+
spin_lock_irqsave(&device_domain_lock, flags);
4611+
dev_iommu_priv_set(dev, NULL);
4612+
list_del(&info->global);
4613+
spin_unlock_irqrestore(&device_domain_lock, flags);
4614+
4615+
kfree(info);
46674616
set_dma_ops(dev, NULL);
46684617
}
46694618

@@ -4732,23 +4681,22 @@ static void intel_iommu_get_resv_regions(struct device *device,
47324681

47334682
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
47344683
{
4735-
struct device_domain_info *info;
4684+
struct device_domain_info *info = dev_iommu_priv_get(dev);
47364685
struct context_entry *context;
47374686
struct dmar_domain *domain;
47384687
unsigned long flags;
47394688
u64 ctx_lo;
47404689
int ret;
47414690

4742-
domain = find_domain(dev);
4691+
domain = info->domain;
47434692
if (!domain)
47444693
return -EINVAL;
47454694

47464695
spin_lock_irqsave(&device_domain_lock, flags);
47474696
spin_lock(&iommu->lock);
47484697

47494698
ret = -EINVAL;
4750-
info = get_domain_info(dev);
4751-
if (!info || !info->pasid_supported)
4699+
if (!info->pasid_supported)
47524700
goto out;
47534701

47544702
context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
@@ -4790,7 +4738,7 @@ static struct iommu_group *intel_iommu_device_group(struct device *dev)
47904738

47914739
static int intel_iommu_enable_sva(struct device *dev)
47924740
{
4793-
struct device_domain_info *info = get_domain_info(dev);
4741+
struct device_domain_info *info = dev_iommu_priv_get(dev);
47944742
struct intel_iommu *iommu;
47954743
int ret;
47964744

@@ -4819,7 +4767,7 @@ static int intel_iommu_enable_sva(struct device *dev)
48194767

48204768
static int intel_iommu_disable_sva(struct device *dev)
48214769
{
4822-
struct device_domain_info *info = get_domain_info(dev);
4770+
struct device_domain_info *info = dev_iommu_priv_get(dev);
48234771
struct intel_iommu *iommu = info->iommu;
48244772
int ret;
48254773

@@ -4832,7 +4780,7 @@ static int intel_iommu_disable_sva(struct device *dev)
48324780

48334781
static int intel_iommu_enable_iopf(struct device *dev)
48344782
{
4835-
struct device_domain_info *info = get_domain_info(dev);
4783+
struct device_domain_info *info = dev_iommu_priv_get(dev);
48364784

48374785
if (info && info->pri_supported)
48384786
return 0;
@@ -4872,7 +4820,9 @@ intel_iommu_dev_disable_feat(struct device *dev, enum iommu_dev_features feat)
48724820

48734821
static bool intel_iommu_is_attach_deferred(struct device *dev)
48744822
{
4875-
return attach_deferred(dev);
4823+
struct device_domain_info *info = dev_iommu_priv_get(dev);
4824+
4825+
return translation_pre_enabled(info->iommu) && !info->domain;
48764826
}
48774827

48784828
/*

drivers/iommu/intel/pasid.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ int intel_pasid_alloc_table(struct device *dev)
150150
int size;
151151

152152
might_sleep();
153-
info = get_domain_info(dev);
153+
info = dev_iommu_priv_get(dev);
154154
if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table))
155155
return -EINVAL;
156156

@@ -197,7 +197,7 @@ void intel_pasid_free_table(struct device *dev)
197197
struct pasid_entry *table;
198198
int i, max_pde;
199199

200-
info = get_domain_info(dev);
200+
info = dev_iommu_priv_get(dev);
201201
if (!info || !dev_is_pci(dev) || !info->pasid_table)
202202
return;
203203

@@ -223,7 +223,7 @@ struct pasid_table *intel_pasid_get_table(struct device *dev)
223223
{
224224
struct device_domain_info *info;
225225

226-
info = get_domain_info(dev);
226+
info = dev_iommu_priv_get(dev);
227227
if (!info)
228228
return NULL;
229229

@@ -234,7 +234,7 @@ static int intel_pasid_get_dev_max_id(struct device *dev)
234234
{
235235
struct device_domain_info *info;
236236

237-
info = get_domain_info(dev);
237+
info = dev_iommu_priv_get(dev);
238238
if (!info || !info->pasid_table)
239239
return 0;
240240

@@ -254,7 +254,7 @@ static struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid)
254254
return NULL;
255255

256256
dir = pasid_table->table;
257-
info = get_domain_info(dev);
257+
info = dev_iommu_priv_get(dev);
258258
dir_index = pasid >> PASID_PDE_SHIFT;
259259
index = pasid & PASID_PTE_MASK;
260260

@@ -487,7 +487,7 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu,
487487
struct device_domain_info *info;
488488
u16 sid, qdep, pfsid;
489489

490-
info = get_domain_info(dev);
490+
info = dev_iommu_priv_get(dev);
491491
if (!info || !info->ats_enabled)
492492
return;
493493

0 commit comments

Comments
 (0)