Commit 96c132f8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull iommu fixes from Joerg Roedel:

 - Important fix for the AMD IOMMU driver in the recently added
   page-specific invalidation code to fix a calculation.

 - Fix a NULL-ptr dereference in the AMD IOMMU driver when a device
   switches domain types.

 - Fixes for the Intel VT-d driver to check for allocation failure and
   do correct cleanup.

 - Another fix for Intel VT-d to not allow supervisor page requests from
   devices when using second level page translation.

 - Add a MODULE_DEVICE_TABLE to the VIRTIO IOMMU driver

* tag 'iommu-fixes-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu/vt-d: Fix sysfs leak in alloc_iommu()
  iommu/vt-d: Use user privilege for RID2PASID translation
  iommu/vt-d: Check for allocation failure in aux_detach_device()
  iommu/virtio: Add missing MODULE_DEVICE_TABLE
  iommu/amd: Fix wrong parentheses on page-specific invalidations
  iommu/amd: Clear DMA ops when switching domain
parents f610a5a2 0ee74d5a
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -884,7 +884,7 @@ static inline u64 build_inv_address(u64 address, size_t size)
		 * The msb-bit must be clear on the address. Just set all the
		 * lower bits.
		 */
		address |= 1ull << (msb_diff - 1);
		address |= (1ull << msb_diff) - 1;
	}

	/* Clear bits 11:0 */
@@ -1714,6 +1714,8 @@ static void amd_iommu_probe_finalize(struct device *dev)
	domain = iommu_get_domain_for_dev(dev);
	if (domain->type == IOMMU_DOMAIN_DMA)
		iommu_setup_dma_ops(dev, IOVA_START_PFN << PAGE_SHIFT, 0);
	else
		set_dma_ops(dev, NULL);
}

static void amd_iommu_release_device(struct device *dev)
+3 −1
Original line number Diff line number Diff line
@@ -1142,7 +1142,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)

		err = iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL);
		if (err)
			goto err_unmap;
			goto err_sysfs;
	}

	drhd->iommu = iommu;
@@ -1150,6 +1150,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)

	return 0;

err_sysfs:
	iommu_device_sysfs_remove(&iommu->iommu);
err_unmap:
	unmap_iommu(iommu);
error_free_seq_id:
+7 −2
Original line number Diff line number Diff line
@@ -2525,9 +2525,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
				    struct device *dev,
				    u32 pasid)
{
	int flags = PASID_FLAG_SUPERVISOR_MODE;
	struct dma_pte *pgd = domain->pgd;
	int agaw, level;
	int flags = 0;

	/*
	 * Skip top levels of page tables for iommu which has
@@ -2543,7 +2543,10 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
	if (level != 4 && level != 5)
		return -EINVAL;

	flags |= (level == 5) ? PASID_FLAG_FL5LP : 0;
	if (pasid != PASID_RID2PASID)
		flags |= PASID_FLAG_SUPERVISOR_MODE;
	if (level == 5)
		flags |= PASID_FLAG_FL5LP;

	if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED)
		flags |= PASID_FLAG_PAGE_SNOOP;
@@ -4606,6 +4609,8 @@ static int auxiliary_link_device(struct dmar_domain *domain,

	if (!sinfo) {
		sinfo = kzalloc(sizeof(*sinfo), GFP_ATOMIC);
		if (!sinfo)
			return -ENOMEM;
		sinfo->domain = domain;
		sinfo->pdev = dev;
		list_add(&sinfo->link_phys, &info->subdevices);
+2 −1
Original line number Diff line number Diff line
@@ -699,6 +699,7 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
	 * Since it is a second level only translation setup, we should
	 * set SRE bit as well (addresses are expected to be GPAs).
	 */
	if (pasid != PASID_RID2PASID)
		pasid_set_sre(pte);
	pasid_set_present(pte);
	pasid_flush_caches(iommu, pte, pasid, did);
+1 −0
Original line number Diff line number Diff line
@@ -1136,6 +1136,7 @@ static struct virtio_device_id id_table[] = {
	{ VIRTIO_ID_IOMMU, VIRTIO_DEV_ANY_ID },
	{ 0 },
};
MODULE_DEVICE_TABLE(virtio, id_table);

static struct virtio_driver virtio_iommu_drv = {
	.driver.name		= KBUILD_MODNAME,