mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 21:33:52 +00:00
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 <baolu.lu@linux.intel.com> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Link: https://lore.kernel.org/r/20230802212427.1497170-6-jacob.jun.pan@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
b61701881f
commit
154786235d
3 changed files with 23 additions and 26 deletions
|
@ -4727,21 +4727,29 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
|
|||
struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
|
||||
struct iommu_domain *domain;
|
||||
|
||||
/* Domain type specific cleanup: */
|
||||
domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0);
|
||||
if (domain) {
|
||||
switch (domain->type) {
|
||||
case IOMMU_DOMAIN_SVA:
|
||||
if (WARN_ON_ONCE(!domain))
|
||||
goto out_tear_down;
|
||||
|
||||
/*
|
||||
* The SVA implementation needs to handle its own stuffs like the mm
|
||||
* notification. Before consolidating that code into iommu core, let
|
||||
* the intel sva code handle it.
|
||||
*/
|
||||
if (domain->type == IOMMU_DOMAIN_SVA) {
|
||||
intel_svm_remove_dev_pasid(dev, pasid);
|
||||
break;
|
||||
default:
|
||||
/* should never reach here */
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
goto out_tear_down;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should never reach here until we add support for attaching
|
||||
* non-SVA domain to a pasid.
|
||||
*/
|
||||
WARN_ON(1);
|
||||
|
||||
out_tear_down:
|
||||
intel_pasid_tear_down_entry(iommu, dev, pasid, false);
|
||||
intel_drain_pasid_prq(dev, pasid);
|
||||
}
|
||||
|
||||
const struct iommu_ops intel_iommu_ops = {
|
||||
|
|
|
@ -844,6 +844,7 @@ int intel_svm_page_response(struct device *dev, struct iommu_fault_event *evt,
|
|||
struct iommu_page_response *msg);
|
||||
struct iommu_domain *intel_svm_domain_alloc(void);
|
||||
void intel_svm_remove_dev_pasid(struct device *dev, ioasid_t pasid);
|
||||
void intel_drain_pasid_prq(struct device *dev, u32 pasid);
|
||||
|
||||
struct intel_svm_dev {
|
||||
struct list_head list;
|
||||
|
@ -862,6 +863,7 @@ struct intel_svm {
|
|||
};
|
||||
#else
|
||||
static inline void intel_svm_check(struct intel_iommu *iommu) {}
|
||||
static inline void intel_drain_pasid_prq(struct device *dev, u32 pasid) {}
|
||||
static inline struct iommu_domain *intel_svm_domain_alloc(void)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include "trace.h"
|
||||
|
||||
static irqreturn_t prq_event_thread(int irq, void *d);
|
||||
static void intel_svm_drain_prq(struct device *dev, u32 pasid);
|
||||
#define to_intel_svm_dev(handle) container_of(handle, struct intel_svm_dev, sva)
|
||||
|
||||
static DEFINE_XARRAY_ALLOC(pasid_private_array);
|
||||
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)
|
|||
|
||||
if (sdev) {
|
||||
list_del_rcu(&sdev->list);
|
||||
/*
|
||||
* Flush the PASID cache and IOTLB for this device.
|
||||
* Note that we do depend on the hardware *not* using
|
||||
* the PASID any more. Just as we depend on other
|
||||
* devices never using PASIDs that they have no right
|
||||
* to use. We have a *shared* PASID table, because it's
|
||||
* large and has to be physically contiguous. So it's
|
||||
* hard to be as defensive as we might like.
|
||||
*/
|
||||
intel_pasid_tear_down_entry(iommu, dev, svm->pasid, false);
|
||||
intel_svm_drain_prq(dev, svm->pasid);
|
||||
kfree_rcu(sdev, rcu);
|
||||
|
||||
if (list_empty(&svm->devs)) {
|
||||
|
@ -449,7 +436,7 @@ static bool is_canonical_address(u64 addr)
|
|||
}
|
||||
|
||||
/**
|
||||
* intel_svm_drain_prq - Drain page requests and responses for a pasid
|
||||
* intel_drain_pasid_prq - Drain page requests and responses for a pasid
|
||||
* @dev: target device
|
||||
* @pasid: pasid for draining
|
||||
*
|
||||
|
@ -463,7 +450,7 @@ static bool is_canonical_address(u64 addr)
|
|||
* described in VT-d spec CH7.10 to drain all page requests and page
|
||||
* responses pending in the hardware.
|
||||
*/
|
||||
static void intel_svm_drain_prq(struct device *dev, u32 pasid)
|
||||
void intel_drain_pasid_prq(struct device *dev, u32 pasid)
|
||||
{
|
||||
struct device_domain_info *info;
|
||||
struct dmar_domain *domain;
|
||||
|
|
Loading…
Reference in a new issue