aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-22 12:06:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-22 12:06:22 -0400
commit1ae45cf06cb7a7dcda781d8d00da4888abb21a69 (patch)
tree20fa9f79736b1af97f92324eee36a3398055e08d
parent5317821c08533e5f42f974e4e68e092beaf099b1 (diff)
parent9db4ad9183aad0e9567f6afb23db1bdc9aa6c2a9 (diff)
Merge tag 'iommu-fixes-v3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU fixes from Joerg Roedel: "The fixes include: - fix a crash in the VT-d driver when devices with a driver attached are hot-unplugged - fix a AMD IOMMU driver crash with device assignment of 32 bit PCI devices to KVM guests - fix for a copy&paste error in generic IOMMU code. Now the right function pointer is checked before calling" * tag 'iommu-fixes-v3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/core: Check for the right function pointer in iommu_map() iommu/amd: Fix cleanup_domain for mass device removal iommu/vt-d: Defer domain removal if device is assigned to a driver
-rw-r--r--drivers/iommu/amd_iommu.c10
-rw-r--r--drivers/iommu/intel-iommu.c8
-rw-r--r--drivers/iommu/iommu.c2
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
3150static void cleanup_domain(struct protection_domain *domain) 3150static 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