Skip to content

Commit 0faa19a

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Decouple PASID & PRI enabling from SVA
Previously the PCI PASID and PRI capabilities are enabled in the path of iommu device probe only if INTEL_IOMMU_SVM is configured and the device supports ATS. As we've already decoupled the I/O page fault handler from SVA, we could also decouple PASID and PRI enabling from it to make room for growth of new features like kernel DMA with PASID, SIOV and nested translation. At the same time, the iommu_enable_dev_iotlb() helper is also called in iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA) path. It's unnecessary and duplicate. This cleanups this helper to make the code neat. Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 06f4b8d commit 0faa19a

File tree

3 files changed

+18
-66
lines changed

3 files changed

+18
-66
lines changed

drivers/iommu/intel/Kconfig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ config INTEL_IOMMU
2121
select IOASID
2222
select IOMMU_DMA
2323
select PCI_ATS
24+
select PCI_PRI
25+
select PCI_PASID
2426
help
2527
DMA remapping (DMAR) devices support enables independent address
2628
translations for Direct Memory Access (DMA) from devices.
@@ -48,10 +50,7 @@ config INTEL_IOMMU_DEBUGFS
4850
config INTEL_IOMMU_SVM
4951
bool "Support for Shared Virtual Memory with Intel IOMMU"
5052
depends on X86_64
51-
select PCI_PASID
52-
select PCI_PRI
5353
select MMU_NOTIFIER
54-
select IOASID
5554
select IOMMU_SVA
5655
help
5756
Shared Virtual Memory (SVM) provides a facility for devices

drivers/iommu/intel/iommu.c

Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ static inline void context_set_domain_id(struct context_entry *context,
199199
context->hi |= (value & ((1 << 16) - 1)) << 8;
200200
}
201201

202+
static inline void context_set_pasid(struct context_entry *context)
203+
{
204+
context->lo |= CONTEXT_PASIDE;
205+
}
206+
202207
static inline int context_domain_id(struct context_entry *c)
203208
{
204209
return((c->hi >> 8) & 0xffff);
@@ -1350,21 +1355,18 @@ static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
13501355
}
13511356

13521357
static struct device_domain_info *
1353-
iommu_support_dev_iotlb(struct dmar_domain *domain, struct intel_iommu *iommu,
1354-
u8 bus, u8 devfn)
1358+
domain_lookup_dev_info(struct dmar_domain *domain,
1359+
struct intel_iommu *iommu, u8 bus, u8 devfn)
13551360
{
13561361
struct device_domain_info *info;
13571362
unsigned long flags;
13581363

1359-
if (!iommu->qi)
1360-
return NULL;
1361-
13621364
spin_lock_irqsave(&domain->lock, flags);
13631365
list_for_each_entry(info, &domain->devices, link) {
13641366
if (info->iommu == iommu && info->bus == bus &&
13651367
info->devfn == devfn) {
13661368
spin_unlock_irqrestore(&domain->lock, flags);
1367-
return info->ats_supported ? info : NULL;
1369+
return info;
13681370
}
13691371
}
13701372
spin_unlock_irqrestore(&domain->lock, flags);
@@ -1389,7 +1391,7 @@ static void domain_update_iotlb(struct dmar_domain *domain)
13891391
spin_unlock_irqrestore(&domain->lock, flags);
13901392
}
13911393

1392-
static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1394+
static void iommu_enable_pci_caps(struct device_domain_info *info)
13931395
{
13941396
struct pci_dev *pdev;
13951397

@@ -1412,7 +1414,6 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
14121414
info->pfsid = pci_dev_id(pf_pdev);
14131415
}
14141416

1415-
#ifdef CONFIG_INTEL_IOMMU_SVM
14161417
/* The PCIe spec, in its wisdom, declares that the behaviour of
14171418
the device if you enable PASID support after ATS support is
14181419
undefined. So always enable PASID support on devices which
@@ -1425,7 +1426,7 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
14251426
(info->pasid_enabled ? pci_prg_resp_pasid_required(pdev) : 1) &&
14261427
!pci_reset_pri(pdev) && !pci_enable_pri(pdev, PRQ_DEPTH))
14271428
info->pri_enabled = 1;
1428-
#endif
1429+
14291430
if (info->ats_supported && pci_ats_page_aligned(pdev) &&
14301431
!pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
14311432
info->ats_enabled = 1;
@@ -1448,16 +1449,16 @@ static void iommu_disable_dev_iotlb(struct device_domain_info *info)
14481449
info->ats_enabled = 0;
14491450
domain_update_iotlb(info->domain);
14501451
}
1451-
#ifdef CONFIG_INTEL_IOMMU_SVM
1452+
14521453
if (info->pri_enabled) {
14531454
pci_disable_pri(pdev);
14541455
info->pri_enabled = 0;
14551456
}
1457+
14561458
if (info->pasid_enabled) {
14571459
pci_disable_pasid(pdev);
14581460
info->pasid_enabled = 0;
14591461
}
1460-
#endif
14611462
}
14621463

14631464
static void __iommu_flush_dev_iotlb(struct device_domain_info *info,
@@ -1907,7 +1908,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
19071908
u8 bus, u8 devfn)
19081909
{
19091910
struct device_domain_info *info =
1910-
iommu_support_dev_iotlb(domain, iommu, bus, devfn);
1911+
domain_lookup_dev_info(domain, iommu, bus, devfn);
19111912
u16 did = domain_id_iommu(domain, iommu);
19121913
int translation = CONTEXT_TT_MULTI_LEVEL;
19131914
struct context_entry *context;
@@ -1980,6 +1981,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
19801981
context_set_sm_dte(context);
19811982
if (info && info->pri_supported)
19821983
context_set_sm_pre(context);
1984+
if (info && info->pasid_supported)
1985+
context_set_pasid(context);
19831986
} else {
19841987
struct dma_pte *pgd = domain->pgd;
19851988
int agaw;
@@ -2037,7 +2040,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
20372040
} else {
20382041
iommu_flush_write_buffer(iommu);
20392042
}
2040-
iommu_enable_dev_iotlb(info);
2043+
iommu_enable_pci_caps(info);
20412044

20422045
ret = 0;
20432046

@@ -4574,52 +4577,6 @@ static void intel_iommu_get_resv_regions(struct device *device,
45744577
list_add_tail(&reg->list, head);
45754578
}
45764579

4577-
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
4578-
{
4579-
struct device_domain_info *info = dev_iommu_priv_get(dev);
4580-
struct context_entry *context;
4581-
struct dmar_domain *domain;
4582-
u64 ctx_lo;
4583-
int ret;
4584-
4585-
domain = info->domain;
4586-
if (!domain)
4587-
return -EINVAL;
4588-
4589-
spin_lock(&iommu->lock);
4590-
ret = -EINVAL;
4591-
if (!info->pasid_supported)
4592-
goto out;
4593-
4594-
context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
4595-
if (WARN_ON(!context))
4596-
goto out;
4597-
4598-
ctx_lo = context[0].lo;
4599-
4600-
if (!(ctx_lo & CONTEXT_PASIDE)) {
4601-
ctx_lo |= CONTEXT_PASIDE;
4602-
context[0].lo = ctx_lo;
4603-
wmb();
4604-
iommu->flush.flush_context(iommu,
4605-
domain_id_iommu(domain, iommu),
4606-
PCI_DEVID(info->bus, info->devfn),
4607-
DMA_CCMD_MASK_NOBIT,
4608-
DMA_CCMD_DEVICE_INVL);
4609-
}
4610-
4611-
/* Enable PASID support in the device, if it wasn't already */
4612-
if (!info->pasid_enabled)
4613-
iommu_enable_dev_iotlb(info);
4614-
4615-
ret = 0;
4616-
4617-
out:
4618-
spin_unlock(&iommu->lock);
4619-
4620-
return ret;
4621-
}
4622-
46234580
static struct iommu_group *intel_iommu_device_group(struct device *dev)
46244581
{
46254582
if (dev_is_pci(dev))
@@ -4643,9 +4600,6 @@ static int intel_iommu_enable_sva(struct device *dev)
46434600
if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE))
46444601
return -ENODEV;
46454602

4646-
if (intel_iommu_enable_pasid(iommu, dev))
4647-
return -ENODEV;
4648-
46494603
if (!info->pasid_enabled || !info->pri_enabled || !info->ats_enabled)
46504604
return -EINVAL;
46514605

drivers/iommu/intel/iommu.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,6 @@ extern int dmar_ir_support(void);
742742
void *alloc_pgtable_page(int node);
743743
void free_pgtable_page(void *vaddr);
744744
void iommu_flush_write_buffer(struct intel_iommu *iommu);
745-
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev);
746745
struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
747746

748747
#ifdef CONFIG_INTEL_IOMMU_SVM

0 commit comments

Comments
 (0)