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
This commit is contained in:
@@ -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 @@ out_unmap:
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user