diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-07-28 10:58:47 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-07-30 04:28:48 -0400 |
commit | 55c99a4dc50fb749076592e8c66c235ca0124360 (patch) | |
tree | c29a668167d2a503fe021e0153af1c5e0423a889 | |
parent | cbfe8fa6cd672011c755c3cd85c9ffd4e2d10a6f (diff) |
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: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/amd_iommu_v2.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index 3465faf1809e..f7b875bb70d4 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c | |||
@@ -132,11 +132,19 @@ static struct device_state *get_device_state(u16 devid) | |||
132 | 132 | ||
133 | static void free_device_state(struct device_state *dev_state) | 133 | static void free_device_state(struct device_state *dev_state) |
134 | { | 134 | { |
135 | struct iommu_group *group; | ||
136 | |||
135 | /* | 137 | /* |
136 | * First detach device from domain - No more PRI requests will arrive | 138 | * First detach device from domain - No more PRI requests will arrive |
137 | * from that device after it is unbound from the IOMMUv2 domain. | 139 | * from that device after it is unbound from the IOMMUv2 domain. |
138 | */ | 140 | */ |
139 | iommu_detach_device(dev_state->domain, &dev_state->pdev->dev); | 141 | group = iommu_group_get(&dev_state->pdev->dev); |
142 | if (WARN_ON(!group)) | ||
143 | return; | ||
144 | |||
145 | iommu_detach_group(dev_state->domain, group); | ||
146 | |||
147 | iommu_group_put(group); | ||
140 | 148 | ||
141 | /* Everything is down now, free the IOMMUv2 domain */ | 149 | /* Everything is down now, free the IOMMUv2 domain */ |
142 | iommu_domain_free(dev_state->domain); | 150 | iommu_domain_free(dev_state->domain); |
@@ -731,6 +739,7 @@ EXPORT_SYMBOL(amd_iommu_unbind_pasid); | |||
731 | int amd_iommu_init_device(struct pci_dev *pdev, int pasids) | 739 | int amd_iommu_init_device(struct pci_dev *pdev, int pasids) |
732 | { | 740 | { |
733 | struct device_state *dev_state; | 741 | struct device_state *dev_state; |
742 | struct iommu_group *group; | ||
734 | unsigned long flags; | 743 | unsigned long flags; |
735 | int ret, tmp; | 744 | int ret, tmp; |
736 | u16 devid; | 745 | u16 devid; |
@@ -776,10 +785,16 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids) | |||
776 | if (ret) | 785 | if (ret) |
777 | goto out_free_domain; | 786 | goto out_free_domain; |
778 | 787 | ||
779 | ret = iommu_attach_device(dev_state->domain, &pdev->dev); | 788 | group = iommu_group_get(&pdev->dev); |
780 | if (ret != 0) | 789 | if (!group) |
781 | goto out_free_domain; | 790 | goto out_free_domain; |
782 | 791 | ||
792 | ret = iommu_attach_group(dev_state->domain, group); | ||
793 | if (ret != 0) | ||
794 | goto out_drop_group; | ||
795 | |||
796 | iommu_group_put(group); | ||
797 | |||
783 | spin_lock_irqsave(&state_lock, flags); | 798 | spin_lock_irqsave(&state_lock, flags); |
784 | 799 | ||
785 | if (__get_device_state(devid) != NULL) { | 800 | if (__get_device_state(devid) != NULL) { |
@@ -794,6 +809,9 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids) | |||
794 | 809 | ||
795 | return 0; | 810 | return 0; |
796 | 811 | ||
812 | out_drop_group: | ||
813 | iommu_group_put(group); | ||
814 | |||
797 | out_free_domain: | 815 | out_free_domain: |
798 | iommu_domain_free(dev_state->domain); | 816 | iommu_domain_free(dev_state->domain); |
799 | 817 | ||