[PATCH] iommu/amd: Update domain into to dte entry during device driver init

From: Baoquan He
Date: Sun Sep 11 2016 - 20:05:15 EST


All devices are supposed to reset themselves at device driver initialization
stage. At this time if in kdump kernel those on-flight DMA will be stopped
because of device reset. It's best time to update the protection domain info,
especially pte_root, to dte entry which the device relates to. Usually
device driver initialization will call set_dma_mask to set the
limitation of dma address. Do it in set_dma_mask call-back is a good
chance.

Signed-off-by: Baoquan He <bhe@xxxxxxxxxx>
---
drivers/iommu/amd_iommu.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 6c37300..2a0b1ce 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2653,6 +2653,27 @@ static int amd_iommu_dma_supported(struct device *dev, u64 mask)
return check_device(dev);
}

+static int set_dma_mask(struct device *dev, u64 mask)
+{
+ struct iommu_dev_data *dev_data = get_dev_data(dev);
+ struct protection_domain *domain = get_domain(dev);
+ u16 alias = amd_iommu_alias_table[dev_data->devid];
+ struct amd_iommu *iommu = amd_iommu_rlookup_table[dev_data->devid];
+
+ if (translation_pre_enabled(iommu) && !dev_data->domain_updated) {
+ dev_data->domain_updated = true;
+ set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+ if (alias != dev_data->devid)
+ set_dte_entry(alias, domain, dev_data->ats.enabled);
+ device_flush_dte(dev_data);
+ }
+
+ if (!dev->dma_mask || !amd_iommu_dma_supported(dev, mask))
+ return -EIO;
+ *dev->dma_mask = mask;
+ return 0;
+}
+
static struct dma_map_ops amd_iommu_dma_ops = {
.alloc = alloc_coherent,
.free = free_coherent,
@@ -2661,6 +2682,7 @@ static struct dma_map_ops amd_iommu_dma_ops = {
.map_sg = map_sg,
.unmap_sg = unmap_sg,
.dma_supported = amd_iommu_dma_supported,
+ .set_dma_mask = set_dma_mask,
};

static int init_reserved_iova_ranges(void)
--
2.5.5