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: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
2b899390fd
commit
d7cbc0f322
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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);
|
||||||
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_
|
||||||
}
|
}
|
||||||
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);
|
||||||
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 {
|
||||||
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue