diff options
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 10 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 8 | ||||
-rw-r--r-- | drivers/iommu/iommu.c | 2 |
3 files changed, 15 insertions, 5 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 18405314168b..ecb0109a5360 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -3149,14 +3149,16 @@ free_domains: | |||
3149 | 3149 | ||
3150 | static void cleanup_domain(struct protection_domain *domain) | 3150 | static void cleanup_domain(struct protection_domain *domain) |
3151 | { | 3151 | { |
3152 | struct iommu_dev_data *dev_data, *next; | 3152 | struct iommu_dev_data *entry; |
3153 | unsigned long flags; | 3153 | unsigned long flags; |
3154 | 3154 | ||
3155 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 3155 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
3156 | 3156 | ||
3157 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { | 3157 | while (!list_empty(&domain->dev_list)) { |
3158 | __detach_device(dev_data); | 3158 | entry = list_first_entry(&domain->dev_list, |
3159 | atomic_set(&dev_data->bind, 0); | 3159 | struct iommu_dev_data, list); |
3160 | __detach_device(entry); | ||
3161 | atomic_set(&entry->bind, 0); | ||
3160 | } | 3162 | } |
3161 | 3163 | ||
3162 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 3164 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d1f5caad04f9..5619f264862d 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -3869,6 +3869,14 @@ static int device_notifier(struct notifier_block *nb, | |||
3869 | action != BUS_NOTIFY_DEL_DEVICE) | 3869 | action != BUS_NOTIFY_DEL_DEVICE) |
3870 | return 0; | 3870 | return 0; |
3871 | 3871 | ||
3872 | /* | ||
3873 | * If the device is still attached to a device driver we can't | ||
3874 | * tear down the domain yet as DMA mappings may still be in use. | ||
3875 | * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. | ||
3876 | */ | ||
3877 | if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) | ||
3878 | return 0; | ||
3879 | |||
3872 | domain = find_domain(dev); | 3880 | domain = find_domain(dev); |
3873 | if (!domain) | 3881 | if (!domain) |
3874 | return 0; | 3882 | return 0; |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 169836020208..ac4adb337038 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
@@ -995,7 +995,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
995 | size_t orig_size = size; | 995 | size_t orig_size = size; |
996 | int ret = 0; | 996 | int ret = 0; |
997 | 997 | ||
998 | if (unlikely(domain->ops->unmap == NULL || | 998 | if (unlikely(domain->ops->map == NULL || |
999 | domain->ops->pgsize_bitmap == 0UL)) | 999 | domain->ops->pgsize_bitmap == 0UL)) |
1000 | return -ENODEV; | 1000 | return -ENODEV; |
1001 | 1001 | ||