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

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

Merge tag 'iommu-fixes-v5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull IOMMU fixes from Joerg Roedel:
 "A few more fixes this time:

   - Two patches to fix the error path of the map_sg implementation of
     the AMD IOMMU driver.

   - Also a missing IOTLB flush is fixed in the AMD IOMMU driver.

   - Memory leak fix for the Intel IOMMU driver.

   - Fix a regression in the Mediatek IOMMU driver which caused device
     initialization to fail (seen as broken HDMI output)"

* tag 'iommu-fixes-v5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu/amd: Fix IOMMU page flush when detach device from a domain
  iommu/mediatek: Use correct fwspec in mtk_iommu_add_device()
  iommu/vt-d: Fix memory leak in intel_iommu_put_resv_regions()
  iommu/amd: Unmap all mapped pages in error path of map_sg
  iommu/amd: Call free_iova_fast with pfn in map_sg
parents 877ef51d 9825bd94
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -1991,16 +1991,13 @@ static void do_attach(struct iommu_dev_data *dev_data,

static void do_detach(struct iommu_dev_data *dev_data)
{
	struct protection_domain *domain = dev_data->domain;
	struct amd_iommu *iommu;
	u16 alias;

	iommu = amd_iommu_rlookup_table[dev_data->devid];
	alias = dev_data->alias;

	/* decrease reference counters */
	dev_data->domain->dev_iommu[iommu->index] -= 1;
	dev_data->domain->dev_cnt                 -= 1;

	/* Update data structures */
	dev_data->domain = NULL;
	list_del(&dev_data->list);
@@ -2010,6 +2007,16 @@ static void do_detach(struct iommu_dev_data *dev_data)

	/* Flush the DTE entry */
	device_flush_dte(dev_data);

	/* Flush IOTLB */
	domain_flush_tlb_pde(domain);

	/* Wait for the flushes to finish */
	domain_flush_complete(domain);

	/* decrease reference counters - needs to happen after the flushes */
	domain->dev_iommu[iommu->index] -= 1;
	domain->dev_cnt                 -= 1;
}

/*
@@ -2617,13 +2624,13 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
			bus_addr  = address + s->dma_address + (j << PAGE_SHIFT);
			iommu_unmap_page(domain, bus_addr, PAGE_SIZE);

			if (--mapped_pages)
			if (--mapped_pages == 0)
				goto out_free_iova;
		}
	}

out_free_iova:
	free_iova_fast(&dma_dom->iovad, address, npages);
	free_iova_fast(&dma_dom->iovad, address >> PAGE_SHIFT, npages);

out_err:
	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -5294,7 +5294,7 @@ static void intel_iommu_put_resv_regions(struct device *dev,
	struct iommu_resv_region *entry, *next;

	list_for_each_entry_safe(entry, next, head, list) {
		if (entry->type == IOMMU_RESV_RESERVED)
		if (entry->type == IOMMU_RESV_MSI)
			kfree(entry);
	}
}
+4 −0
Original line number Diff line number Diff line
@@ -441,6 +441,10 @@ static int mtk_iommu_add_device(struct device *dev)
		iommu_spec.args_count = count;

		mtk_iommu_create_mapping(dev, &iommu_spec);

		/* dev->iommu_fwspec might have changed */
		fwspec = dev_iommu_fwspec_get(dev);

		of_node_put(iommu_spec.np);
	}