Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ae45cf0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 5317821c 9db4ad91
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -3149,14 +3149,16 @@ int __init amd_iommu_init_dma_ops(void)

static void cleanup_domain(struct protection_domain *domain)
{
	struct iommu_dev_data *dev_data, *next;
	struct iommu_dev_data *entry;
	unsigned long flags;

	write_lock_irqsave(&amd_iommu_devtable_lock, flags);

	list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
		__detach_device(dev_data);
		atomic_set(&dev_data->bind, 0);
	while (!list_empty(&domain->dev_list)) {
		entry = list_first_entry(&domain->dev_list,
					 struct iommu_dev_data, list);
		__detach_device(entry);
		atomic_set(&entry->bind, 0);
	}

	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+8 −0
Original line number Diff line number Diff line
@@ -3869,6 +3869,14 @@ static int device_notifier(struct notifier_block *nb,
	    action != BUS_NOTIFY_DEL_DEVICE)
		return 0;

	/*
	 * If the device is still attached to a device driver we can't
	 * tear down the domain yet as DMA mappings may still be in use.
	 * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that.
	 */
	if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL)
		return 0;

	domain = find_domain(dev);
	if (!domain)
		return 0;
+1 −1
Original line number Diff line number Diff line
@@ -995,7 +995,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
	size_t orig_size = size;
	int ret = 0;

	if (unlikely(domain->ops->unmap == NULL ||
	if (unlikely(domain->ops->map == NULL ||
		     domain->ops->pgsize_bitmap == 0UL))
		return -ENODEV;