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

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
...@@ -884,7 +884,7 @@ static inline u64 build_inv_address(u64 address, size_t size) ...@@ -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 * The msb-bit must be clear on the address. Just set all the
* lower bits. * lower bits.
*/ */
address |= 1ull << (msb_diff - 1); address |= (1ull << msb_diff) - 1;
} }
/* Clear bits 11:0 */ /* Clear bits 11:0 */
...@@ -1714,6 +1714,8 @@ static void amd_iommu_probe_finalize(struct device *dev) ...@@ -1714,6 +1714,8 @@ static void amd_iommu_probe_finalize(struct device *dev)
domain = iommu_get_domain_for_dev(dev); domain = iommu_get_domain_for_dev(dev);
if (domain->type == IOMMU_DOMAIN_DMA) if (domain->type == IOMMU_DOMAIN_DMA)
iommu_setup_dma_ops(dev, IOVA_START_PFN << PAGE_SHIFT, 0); 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) static void amd_iommu_release_device(struct device *dev)
......
...@@ -1142,7 +1142,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) ...@@ -1142,7 +1142,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
err = iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL); err = iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL);
if (err) if (err)
goto err_unmap; goto err_sysfs;
} }
drhd->iommu = iommu; drhd->iommu = iommu;
...@@ -1150,6 +1150,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) ...@@ -1150,6 +1150,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
return 0; return 0;
err_sysfs:
iommu_device_sysfs_remove(&iommu->iommu);
err_unmap: err_unmap:
unmap_iommu(iommu); unmap_iommu(iommu);
error_free_seq_id: error_free_seq_id:
......
...@@ -2525,9 +2525,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu, ...@@ -2525,9 +2525,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
struct device *dev, struct device *dev,
u32 pasid) u32 pasid)
{ {
int flags = PASID_FLAG_SUPERVISOR_MODE;
struct dma_pte *pgd = domain->pgd; struct dma_pte *pgd = domain->pgd;
int agaw, level; int agaw, level;
int flags = 0;
/* /*
* Skip top levels of page tables for iommu which has * Skip top levels of page tables for iommu which has
...@@ -2543,7 +2543,10 @@ static int domain_setup_first_level(struct intel_iommu *iommu, ...@@ -2543,7 +2543,10 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
if (level != 4 && level != 5) if (level != 4 && level != 5)
return -EINVAL; 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) if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED)
flags |= PASID_FLAG_PAGE_SNOOP; flags |= PASID_FLAG_PAGE_SNOOP;
...@@ -4606,6 +4609,8 @@ static int auxiliary_link_device(struct dmar_domain *domain, ...@@ -4606,6 +4609,8 @@ static int auxiliary_link_device(struct dmar_domain *domain,
if (!sinfo) { if (!sinfo) {
sinfo = kzalloc(sizeof(*sinfo), GFP_ATOMIC); sinfo = kzalloc(sizeof(*sinfo), GFP_ATOMIC);
if (!sinfo)
return -ENOMEM;
sinfo->domain = domain; sinfo->domain = domain;
sinfo->pdev = dev; sinfo->pdev = dev;
list_add(&sinfo->link_phys, &info->subdevices); list_add(&sinfo->link_phys, &info->subdevices);
......
...@@ -699,7 +699,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu, ...@@ -699,7 +699,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
* Since it is a second level only translation setup, we should * Since it is a second level only translation setup, we should
* set SRE bit as well (addresses are expected to be GPAs). * set SRE bit as well (addresses are expected to be GPAs).
*/ */
pasid_set_sre(pte); if (pasid != PASID_RID2PASID)
pasid_set_sre(pte);
pasid_set_present(pte); pasid_set_present(pte);
pasid_flush_caches(iommu, pte, pasid, did); pasid_flush_caches(iommu, pte, pasid, did);
......
...@@ -1136,6 +1136,7 @@ static struct virtio_device_id id_table[] = { ...@@ -1136,6 +1136,7 @@ static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_IOMMU, VIRTIO_DEV_ANY_ID }, { VIRTIO_ID_IOMMU, VIRTIO_DEV_ANY_ID },
{ 0 }, { 0 },
}; };
MODULE_DEVICE_TABLE(virtio, id_table);
static struct virtio_driver virtio_iommu_drv = { static struct virtio_driver virtio_iommu_drv = {
.driver.name = KBUILD_MODNAME, .driver.name = KBUILD_MODNAME,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment