Commit 1615e889 authored by Nicolin Chen's avatar Nicolin Chen Committed by Joerg Roedel
Browse files

iommu: Fix pasid attach in pci_dev_reset_iommu_prepare/done()



Now the helpers handle per-gdev resets. Replace __iommu_set_group_pasid()
with set_dev_pasid() accordingly, in the pci_dev_reset_iommu_done().

Also add max_pasids check as other callers.

Fixes: c279e839 ("iommu: Introduce pci_dev_reset_iommu_prepare/done()")
Cc: stable@vger.kernel.org
Reported-by: default avatarShuai Xue <xueshuai@linux.alibaba.com>
Closes: https://lore.kernel.org/all/ad858513-09fc-455e-bbc5-fe38a225cc78@linux.alibaba.com/


Reviewed-by: default avatarShuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Signed-off-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent b296ca1f
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -4074,9 +4074,14 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
	 * The pasid_array is mostly fenced by group->mutex, except one reader
	 * in iommu_attach_handle_get(), so it's safe to read without xa_lock.
	 */
	xa_for_each_start(&group->pasid_array, pasid, entry, 1)
		iommu_remove_dev_pasid(&pdev->dev, pasid,
				       pasid_array_entry_to_domain(entry));
	if (pdev->dev.iommu->max_pasids > 0) {
		xa_for_each_start(&group->pasid_array, pasid, entry, 1) {
			struct iommu_domain *pasid_dom =
				pasid_array_entry_to_domain(entry);

			iommu_remove_dev_pasid(&pdev->dev, pasid, pasid_dom);
		}
	}

	group->recovery_cnt++;
	return ret;
@@ -4143,10 +4148,16 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
	 * The pasid_array is mostly fenced by group->mutex, except one reader
	 * in iommu_attach_handle_get(), so it's safe to read without xa_lock.
	 */
	xa_for_each_start(&group->pasid_array, pasid, entry, 1)
		WARN_ON(__iommu_set_group_pasid(
			pasid_array_entry_to_domain(entry), group, pasid,
	if (pdev->dev.iommu->max_pasids > 0) {
		xa_for_each_start(&group->pasid_array, pasid, entry, 1) {
			struct iommu_domain *pasid_dom =
				pasid_array_entry_to_domain(entry);

			WARN_ON(pasid_dom->ops->set_dev_pasid(
				pasid_dom, &pdev->dev, pasid,
				group->blocking_domain));
		}
	}

	if (!WARN_ON(group->recovery_cnt == 0))
		group->recovery_cnt--;