Commit d7cbc0f3 authored by Lu Baolu's avatar Lu Baolu Committed by Joerg Roedel

iommu/vt-d: Make intel_iommu_enable_pasid() more generic

This moves intel_iommu_enable_pasid() out of the scope of
CONFIG_INTEL_IOMMU_SVM with more and more features requiring
pasid function.

Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 2b899390
...@@ -5307,8 +5307,7 @@ static void intel_iommu_put_resv_regions(struct device *dev, ...@@ -5307,8 +5307,7 @@ static void intel_iommu_put_resv_regions(struct device *dev,
} }
} }
#ifdef CONFIG_INTEL_IOMMU_SVM int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
{ {
struct device_domain_info *info; struct device_domain_info *info;
struct context_entry *context; struct context_entry *context;
...@@ -5317,7 +5316,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd ...@@ -5317,7 +5316,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
u64 ctx_lo; u64 ctx_lo;
int ret; int ret;
domain = get_valid_domain_for_dev(sdev->dev); domain = get_valid_domain_for_dev(dev);
if (!domain) if (!domain)
return -EINVAL; return -EINVAL;
...@@ -5325,7 +5324,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd ...@@ -5325,7 +5324,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
spin_lock(&iommu->lock); spin_lock(&iommu->lock);
ret = -EINVAL; ret = -EINVAL;
info = sdev->dev->archdata.iommu; info = dev->archdata.iommu;
if (!info || !info->pasid_supported) if (!info || !info->pasid_supported)
goto out; goto out;
...@@ -5335,14 +5334,13 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd ...@@ -5335,14 +5334,13 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
ctx_lo = context[0].lo; ctx_lo = context[0].lo;
sdev->did = FLPT_DEFAULT_DID;
sdev->sid = PCI_DEVID(info->bus, info->devfn);
if (!(ctx_lo & CONTEXT_PASIDE)) { if (!(ctx_lo & CONTEXT_PASIDE)) {
ctx_lo |= CONTEXT_PASIDE; ctx_lo |= CONTEXT_PASIDE;
context[0].lo = ctx_lo; context[0].lo = ctx_lo;
wmb(); wmb();
iommu->flush.flush_context(iommu, sdev->did, sdev->sid, iommu->flush.flush_context(iommu,
domain->iommu_did[iommu->seq_id],
PCI_DEVID(info->bus, info->devfn),
DMA_CCMD_MASK_NOBIT, DMA_CCMD_MASK_NOBIT,
DMA_CCMD_DEVICE_INVL); DMA_CCMD_DEVICE_INVL);
} }
...@@ -5351,12 +5349,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd ...@@ -5351,12 +5349,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
if (!info->pasid_enabled) if (!info->pasid_enabled)
iommu_enable_dev_iotlb(info); iommu_enable_dev_iotlb(info);
if (info->ats_enabled) {
sdev->dev_iotlb = 1;
sdev->qdep = info->ats_qdep;
if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
sdev->qdep = 0;
}
ret = 0; ret = 0;
out: out:
...@@ -5366,6 +5358,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd ...@@ -5366,6 +5358,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
return ret; return ret;
} }
#ifdef CONFIG_INTEL_IOMMU_SVM
struct intel_iommu *intel_svm_device_to_iommu(struct device *dev) struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
{ {
struct intel_iommu *iommu; struct intel_iommu *iommu;
......
...@@ -228,6 +228,7 @@ static LIST_HEAD(global_svm_list); ...@@ -228,6 +228,7 @@ static LIST_HEAD(global_svm_list);
int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops) int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops)
{ {
struct intel_iommu *iommu = intel_svm_device_to_iommu(dev); struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
struct device_domain_info *info;
struct intel_svm_dev *sdev; struct intel_svm_dev *sdev;
struct intel_svm *svm = NULL; struct intel_svm *svm = NULL;
struct mm_struct *mm = NULL; struct mm_struct *mm = NULL;
...@@ -291,13 +292,29 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ ...@@ -291,13 +292,29 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
} }
sdev->dev = dev; sdev->dev = dev;
ret = intel_iommu_enable_pasid(iommu, sdev); ret = intel_iommu_enable_pasid(iommu, dev);
if (ret || !pasid) { if (ret || !pasid) {
/* If they don't actually want to assign a PASID, this is /* If they don't actually want to assign a PASID, this is
* just an enabling check/preparation. */ * just an enabling check/preparation. */
kfree(sdev); kfree(sdev);
goto out; goto out;
} }
info = dev->archdata.iommu;
if (!info || !info->pasid_supported) {
kfree(sdev);
goto out;
}
sdev->did = FLPT_DEFAULT_DID;
sdev->sid = PCI_DEVID(info->bus, info->devfn);
if (info->ats_enabled) {
sdev->dev_iotlb = 1;
sdev->qdep = info->ats_qdep;
if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
sdev->qdep = 0;
}
/* Finish the setup now we know we're keeping it */ /* Finish the setup now we know we're keeping it */
sdev->users = 1; sdev->users = 1;
sdev->ops = ops; sdev->ops = ops;
......
...@@ -650,6 +650,7 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain); ...@@ -650,6 +650,7 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain);
int for_each_device_domain(int (*fn)(struct device_domain_info *info, int for_each_device_domain(int (*fn)(struct device_domain_info *info,
void *data), void *data); void *data), void *data);
void iommu_flush_write_buffer(struct intel_iommu *iommu); void iommu_flush_write_buffer(struct intel_iommu *iommu);
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev);
#ifdef CONFIG_INTEL_IOMMU_SVM #ifdef CONFIG_INTEL_IOMMU_SVM
int intel_svm_init(struct intel_iommu *iommu); int intel_svm_init(struct intel_iommu *iommu);
...@@ -679,7 +680,6 @@ struct intel_svm { ...@@ -679,7 +680,6 @@ struct intel_svm {
struct list_head list; struct list_head list;
}; };
extern int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev);
extern struct intel_iommu *intel_svm_device_to_iommu(struct device *dev); extern struct intel_iommu *intel_svm_device_to_iommu(struct device *dev);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment