Skip to content

Commit c43e1cc

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Drain PRQs when domain removed from RID
As this iommu driver now supports page faults for requests without PASID, page requests should be drained when a domain is removed from the RID2PASID entry. This results in the intel_iommu_drain_pasid_prq() call being moved to intel_pasid_tear_down_entry(). This indicates that when a translation is removed from any PASID entry and the PRI has been enabled on the device, page requests are drained in the domain detachment path. The intel_iommu_drain_pasid_prq() helper has been modified to support sending device TLB invalidation requests for both PASID and non-PASID cases. Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Yi Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 9baed1c commit c43e1cc

File tree

3 files changed

+10
-18
lines changed

3 files changed

+10
-18
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4067,7 +4067,6 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
40674067
intel_iommu_debugfs_remove_dev_pasid(dev_pasid);
40684068
kfree(dev_pasid);
40694069
intel_pasid_tear_down_entry(iommu, dev, pasid, false);
4070-
intel_iommu_drain_pasid_prq(dev, pasid);
40714070
}
40724071

40734072
static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,

drivers/iommu/intel/pasid.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
265265
iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
266266

267267
devtlb_invalidation_with_pasid(iommu, dev, pasid);
268+
intel_iommu_drain_pasid_prq(dev, pasid);
268269
}
269270

270271
/*

drivers/iommu/intel/prq.c

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,18 @@ void intel_iommu_drain_pasid_prq(struct device *dev, u32 pasid)
6363
struct dmar_domain *domain;
6464
struct intel_iommu *iommu;
6565
struct qi_desc desc[3];
66-
struct pci_dev *pdev;
6766
int head, tail;
6867
u16 sid, did;
69-
int qdep;
7068

7169
info = dev_iommu_priv_get(dev);
72-
if (WARN_ON(!info || !dev_is_pci(dev)))
73-
return;
74-
7570
if (!info->pri_enabled)
7671
return;
7772

7873
iommu = info->iommu;
7974
domain = info->domain;
80-
pdev = to_pci_dev(dev);
8175
sid = PCI_DEVID(info->bus, info->devfn);
8276
did = domain ? domain_id_iommu(domain, iommu) : FLPT_DEFAULT_DID;
8377

84-
qdep = pci_ats_queue_depth(pdev);
85-
8678
/*
8779
* Check and wait until all pending page requests in the queue are
8880
* handled by the prq handling thread.
@@ -114,15 +106,15 @@ void intel_iommu_drain_pasid_prq(struct device *dev, u32 pasid)
114106
desc[0].qw0 = QI_IWD_STATUS_DATA(QI_DONE) |
115107
QI_IWD_FENCE |
116108
QI_IWD_TYPE;
117-
desc[1].qw0 = QI_EIOTLB_PASID(pasid) |
118-
QI_EIOTLB_DID(did) |
119-
QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
120-
QI_EIOTLB_TYPE;
121-
desc[2].qw0 = QI_DEV_EIOTLB_PASID(pasid) |
122-
QI_DEV_EIOTLB_SID(sid) |
123-
QI_DEV_EIOTLB_QDEP(qdep) |
124-
QI_DEIOTLB_TYPE |
125-
QI_DEV_IOTLB_PFSID(info->pfsid);
109+
if (pasid == IOMMU_NO_PASID) {
110+
qi_desc_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH, &desc[1]);
111+
qi_desc_dev_iotlb(sid, info->pfsid, info->ats_qdep, 0,
112+
MAX_AGAW_PFN_WIDTH, &desc[2]);
113+
} else {
114+
qi_desc_piotlb(did, pasid, 0, -1, 0, &desc[1]);
115+
qi_desc_dev_iotlb_pasid(sid, info->pfsid, pasid, info->ats_qdep,
116+
0, MAX_AGAW_PFN_WIDTH, &desc[2]);
117+
}
126118
qi_retry:
127119
reinit_completion(&iommu->prq_complete);
128120
qi_submit_sync(iommu, desc, 3, QI_OPT_WAIT_DRAIN);

0 commit comments

Comments
 (0)