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: c279e83953 ("iommu: Introduce pci_dev_reset_iommu_prepare/done()")
Cc: stable@vger.kernel.org
Reported-by: Shuai Xue <xueshuai@linux.alibaba.com>
Closes: https://lore.kernel.org/all/ad858513-09fc-455e-bbc5-fe38a225cc78@linux.alibaba.com/
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
Nicolin Chen 2026-04-24 18:15:23 -07:00 committed by Joerg Roedel
parent b296ca1fb4
commit 1615e8896a

View File

@ -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,
group->blocking_domain));
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--;