When an IOMMU domain with nesting attribute is used for guest SVA, a system-wide PASID is allocated for binding with the device and the domain. For security reason, we need to check the PASID passsed from user-space. e.g. page table bind/unbind and PASID related cache invalidation.
Cc: Kevin Tian <kevin.t...@intel.com> CC: Jacob Pan <jacob.jun....@linux.intel.com> Cc: Alex Williamson <alex.william...@redhat.com> Cc: Eric Auger <eric.au...@redhat.com> Cc: Jean-Philippe Brucker <jean-phili...@linaro.org> Cc: Joerg Roedel <j...@8bytes.org> Cc: Lu Baolu <baolu...@linux.intel.com> Signed-off-by: Liu Yi L <yi.l....@intel.com> Signed-off-by: Jacob Pan <jacob.jun....@linux.intel.com> --- drivers/iommu/intel-iommu.c | 10 ++++++++++ drivers/iommu/intel-svm.c | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 2d59a5d..25650ac 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -5433,6 +5433,7 @@ intel_iommu_sva_invalidate(struct iommu_domain *domain, struct device *dev, int granu = 0; u64 pasid = 0; u64 addr = 0; + void *pdata; granu = to_vtd_granularity(cache_type, inv_info->granularity); if (granu == -EINVAL) { @@ -5452,6 +5453,15 @@ intel_iommu_sva_invalidate(struct iommu_domain *domain, struct device *dev, (inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_PASID)) pasid = inv_info->addr_info.pasid; + pdata = ioasid_find(dmar_domain->ioasid_sid, pasid, NULL); + if (!pdata) { + ret = -EINVAL; + goto out_unlock; + } else if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out_unlock; + } + switch (BIT(cache_type)) { case IOMMU_CACHE_INV_TYPE_IOTLB: /* HW will ignore LSB bits based on address mask */ diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index bf55e2f..49059c1 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -332,7 +332,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, dmar_domain = to_dmar_domain(domain); mutex_lock(&pasid_mutex); - svm = ioasid_find(INVALID_IOASID_SET, data->hpasid, NULL); + svm = ioasid_find(dmar_domain->ioasid_sid, data->hpasid, NULL); if (IS_ERR(svm)) { ret = PTR_ERR(svm); goto out; @@ -450,6 +450,7 @@ int intel_svm_unbind_gpasid(struct iommu_domain *domain, struct iommu_gpasid_unbind_data *data) { struct intel_iommu *iommu = intel_svm_device_to_iommu(dev); + struct dmar_domain *dmar_domain; struct intel_svm_dev *sdev; struct intel_svm *svm; int ret = -EINVAL; @@ -464,9 +465,10 @@ int intel_svm_unbind_gpasid(struct iommu_domain *domain, return -EINVAL; pasid = data->pasid; + dmar_domain = to_dmar_domain(domain); mutex_lock(&pasid_mutex); - svm = ioasid_find(INVALID_IOASID_SET, pasid, NULL); + svm = ioasid_find(dmar_domain->ioasid_sid, pasid, NULL); if (!svm) { ret = -EINVAL; goto out; -- 2.7.4 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu