Skip to content

Commit 1547862

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Make prq draining code generic
Currently draining page requests and responses for a pasid is part of SVA implementation. This is because the driver only supports attaching an SVA domain to a device pasid. As we are about to support attaching other types of domains to a device pasid, the prq draining code becomes generic. Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Jacob Pan <[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 b617018 commit 1547862

File tree

3 files changed

+23
-26
lines changed

3 files changed

+23
-26
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4727,21 +4727,29 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
47274727
struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
47284728
struct iommu_domain *domain;
47294729

4730-
/* Domain type specific cleanup: */
47314730
domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0);
4732-
if (domain) {
4733-
switch (domain->type) {
4734-
case IOMMU_DOMAIN_SVA:
4735-
intel_svm_remove_dev_pasid(dev, pasid);
4736-
break;
4737-
default:
4738-
/* should never reach here */
4739-
WARN_ON(1);
4740-
break;
4741-
}
4731+
if (WARN_ON_ONCE(!domain))
4732+
goto out_tear_down;
4733+
4734+
/*
4735+
* The SVA implementation needs to handle its own stuffs like the mm
4736+
* notification. Before consolidating that code into iommu core, let
4737+
* the intel sva code handle it.
4738+
*/
4739+
if (domain->type == IOMMU_DOMAIN_SVA) {
4740+
intel_svm_remove_dev_pasid(dev, pasid);
4741+
goto out_tear_down;
47424742
}
47434743

4744+
/*
4745+
* Should never reach here until we add support for attaching
4746+
* non-SVA domain to a pasid.
4747+
*/
4748+
WARN_ON(1);
4749+
4750+
out_tear_down:
47444751
intel_pasid_tear_down_entry(iommu, dev, pasid, false);
4752+
intel_drain_pasid_prq(dev, pasid);
47454753
}
47464754

47474755
const struct iommu_ops intel_iommu_ops = {

drivers/iommu/intel/iommu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ int intel_svm_page_response(struct device *dev, struct iommu_fault_event *evt,
844844
struct iommu_page_response *msg);
845845
struct iommu_domain *intel_svm_domain_alloc(void);
846846
void intel_svm_remove_dev_pasid(struct device *dev, ioasid_t pasid);
847+
void intel_drain_pasid_prq(struct device *dev, u32 pasid);
847848

848849
struct intel_svm_dev {
849850
struct list_head list;
@@ -862,6 +863,7 @@ struct intel_svm {
862863
};
863864
#else
864865
static inline void intel_svm_check(struct intel_iommu *iommu) {}
866+
static inline void intel_drain_pasid_prq(struct device *dev, u32 pasid) {}
865867
static inline struct iommu_domain *intel_svm_domain_alloc(void)
866868
{
867869
return NULL;

drivers/iommu/intel/svm.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
#include "trace.h"
2727

2828
static irqreturn_t prq_event_thread(int irq, void *d);
29-
static void intel_svm_drain_prq(struct device *dev, u32 pasid);
30-
#define to_intel_svm_dev(handle) container_of(handle, struct intel_svm_dev, sva)
3129

3230
static DEFINE_XARRAY_ALLOC(pasid_private_array);
3331
static int pasid_private_add(ioasid_t pasid, void *priv)
@@ -382,17 +380,6 @@ void intel_svm_remove_dev_pasid(struct device *dev, u32 pasid)
382380

383381
if (sdev) {
384382
list_del_rcu(&sdev->list);
385-
/*
386-
* Flush the PASID cache and IOTLB for this device.
387-
* Note that we do depend on the hardware *not* using
388-
* the PASID any more. Just as we depend on other
389-
* devices never using PASIDs that they have no right
390-
* to use. We have a *shared* PASID table, because it's
391-
* large and has to be physically contiguous. So it's
392-
* hard to be as defensive as we might like.
393-
*/
394-
intel_pasid_tear_down_entry(iommu, dev, svm->pasid, false);
395-
intel_svm_drain_prq(dev, svm->pasid);
396383
kfree_rcu(sdev, rcu);
397384

398385
if (list_empty(&svm->devs)) {
@@ -449,7 +436,7 @@ static bool is_canonical_address(u64 addr)
449436
}
450437

451438
/**
452-
* intel_svm_drain_prq - Drain page requests and responses for a pasid
439+
* intel_drain_pasid_prq - Drain page requests and responses for a pasid
453440
* @dev: target device
454441
* @pasid: pasid for draining
455442
*
@@ -463,7 +450,7 @@ static bool is_canonical_address(u64 addr)
463450
* described in VT-d spec CH7.10 to drain all page requests and page
464451
* responses pending in the hardware.
465452
*/
466-
static void intel_svm_drain_prq(struct device *dev, u32 pasid)
453+
void intel_drain_pasid_prq(struct device *dev, u32 pasid)
467454
{
468455
struct device_domain_info *info;
469456
struct dmar_domain *domain;

0 commit comments

Comments
 (0)