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

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
......@@ -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;
......
......@@ -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);
}
}
......
......@@ -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);
}
......
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