mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 14:34:28 +08:00
iommu/vt-d: Misc macro clean up for SVM
Use combined macros for_each_svm_dev() to simplify SVM device iteration and error checking. Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com> Reviewed-by: Eric Auger <eric.auger@redhat.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
5f75585e19
commit
034d473109
@ -222,6 +222,10 @@ static const struct mmu_notifier_ops intel_mmuops = {
|
|||||||
static DEFINE_MUTEX(pasid_mutex);
|
static DEFINE_MUTEX(pasid_mutex);
|
||||||
static LIST_HEAD(global_svm_list);
|
static LIST_HEAD(global_svm_list);
|
||||||
|
|
||||||
|
#define for_each_svm_dev(sdev, svm, d) \
|
||||||
|
list_for_each_entry((sdev), &(svm)->devs, list) \
|
||||||
|
if ((d) != (sdev)->dev) {} else
|
||||||
|
|
||||||
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);
|
||||||
@ -270,15 +274,14 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(sdev, &svm->devs, list) {
|
/* Find the matching device in svm list */
|
||||||
if (dev == sdev->dev) {
|
for_each_svm_dev(sdev, svm, dev) {
|
||||||
if (sdev->ops != ops) {
|
if (sdev->ops != ops) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
sdev->users++;
|
|
||||||
goto success;
|
|
||||||
}
|
}
|
||||||
|
sdev->users++;
|
||||||
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -423,40 +426,36 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(sdev, &svm->devs, list) {
|
for_each_svm_dev(sdev, svm, dev) {
|
||||||
if (dev == sdev->dev) {
|
ret = 0;
|
||||||
ret = 0;
|
sdev->users--;
|
||||||
sdev->users--;
|
if (!sdev->users) {
|
||||||
if (!sdev->users) {
|
list_del_rcu(&sdev->list);
|
||||||
list_del_rcu(&sdev->list);
|
/* Flush the PASID cache and IOTLB for this device.
|
||||||
/* Flush the PASID cache and IOTLB for this device.
|
* Note that we do depend on the hardware *not* using
|
||||||
* Note that we do depend on the hardware *not* using
|
* the PASID any more. Just as we depend on other
|
||||||
* the PASID any more. Just as we depend on other
|
* devices never using PASIDs that they have no right
|
||||||
* devices never using PASIDs that they have no right
|
* to use. We have a *shared* PASID table, because it's
|
||||||
* to use. We have a *shared* PASID table, because it's
|
* large and has to be physically contiguous. So it's
|
||||||
* large and has to be physically contiguous. So it's
|
* hard to be as defensive as we might like. */
|
||||||
* hard to be as defensive as we might like. */
|
intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
|
||||||
intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
|
intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
|
||||||
intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
|
kfree_rcu(sdev, rcu);
|
||||||
kfree_rcu(sdev, rcu);
|
|
||||||
|
|
||||||
if (list_empty(&svm->devs)) {
|
if (list_empty(&svm->devs)) {
|
||||||
ioasid_free(svm->pasid);
|
ioasid_free(svm->pasid);
|
||||||
if (svm->mm)
|
if (svm->mm)
|
||||||
mmu_notifier_unregister(&svm->notifier, svm->mm);
|
mmu_notifier_unregister(&svm->notifier, svm->mm);
|
||||||
|
list_del(&svm->list);
|
||||||
list_del(&svm->list);
|
/* We mandate that no page faults may be outstanding
|
||||||
|
* for the PASID when intel_svm_unbind_mm() is called.
|
||||||
/* We mandate that no page faults may be outstanding
|
* If that is not obeyed, subtle errors will happen.
|
||||||
* for the PASID when intel_svm_unbind_mm() is called.
|
* Let's make them less subtle... */
|
||||||
* If that is not obeyed, subtle errors will happen.
|
memset(svm, 0x6b, sizeof(*svm));
|
||||||
* Let's make them less subtle... */
|
kfree(svm);
|
||||||
memset(svm, 0x6b, sizeof(*svm));
|
|
||||||
kfree(svm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&pasid_mutex);
|
mutex_unlock(&pasid_mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user