Commit 55c99a4d authored by Joerg Roedel's avatar Joerg Roedel

iommu/amd: Use iommu_attach_group()

Since the conversion to default domains the
iommu_attach_device function only works for devices with
their own group. But this isn't always true for current
IOMMUv2 capable devices, so use iommu_attach_group instead.
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent cbfe8fa6
...@@ -132,11 +132,19 @@ static struct device_state *get_device_state(u16 devid) ...@@ -132,11 +132,19 @@ static struct device_state *get_device_state(u16 devid)
static void free_device_state(struct device_state *dev_state) static void free_device_state(struct device_state *dev_state)
{ {
struct iommu_group *group;
/* /*
* First detach device from domain - No more PRI requests will arrive * First detach device from domain - No more PRI requests will arrive
* from that device after it is unbound from the IOMMUv2 domain. * from that device after it is unbound from the IOMMUv2 domain.
*/ */
iommu_detach_device(dev_state->domain, &dev_state->pdev->dev); group = iommu_group_get(&dev_state->pdev->dev);
if (WARN_ON(!group))
return;
iommu_detach_group(dev_state->domain, group);
iommu_group_put(group);
/* Everything is down now, free the IOMMUv2 domain */ /* Everything is down now, free the IOMMUv2 domain */
iommu_domain_free(dev_state->domain); iommu_domain_free(dev_state->domain);
...@@ -731,6 +739,7 @@ EXPORT_SYMBOL(amd_iommu_unbind_pasid); ...@@ -731,6 +739,7 @@ EXPORT_SYMBOL(amd_iommu_unbind_pasid);
int amd_iommu_init_device(struct pci_dev *pdev, int pasids) int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
{ {
struct device_state *dev_state; struct device_state *dev_state;
struct iommu_group *group;
unsigned long flags; unsigned long flags;
int ret, tmp; int ret, tmp;
u16 devid; u16 devid;
...@@ -776,10 +785,16 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids) ...@@ -776,10 +785,16 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
if (ret) if (ret)
goto out_free_domain; goto out_free_domain;
ret = iommu_attach_device(dev_state->domain, &pdev->dev); group = iommu_group_get(&pdev->dev);
if (ret != 0) if (!group)
goto out_free_domain; goto out_free_domain;
ret = iommu_attach_group(dev_state->domain, group);
if (ret != 0)
goto out_drop_group;
iommu_group_put(group);
spin_lock_irqsave(&state_lock, flags); spin_lock_irqsave(&state_lock, flags);
if (__get_device_state(devid) != NULL) { if (__get_device_state(devid) != NULL) {
...@@ -794,6 +809,9 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids) ...@@ -794,6 +809,9 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
return 0; return 0;
out_drop_group:
iommu_group_put(group);
out_free_domain: out_free_domain:
iommu_domain_free(dev_state->domain); iommu_domain_free(dev_state->domain);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment