summary refs log tree commit diff
path: root/drivers/pci/intel-iommu.c
diff options
context:
space:
mode:
authorWeidong Han <weidong.han@intel.com>2008-12-08 11:06:32 +0800
committerJoerg Roedel <joerg.roedel@amd.com>2009-01-03 14:02:17 +0100
commitd9630fe941769dd050fbc38fbbac20a708ab9461 (patch)
treea65539265a7b7f73d3b3cb71f86be746821eba00 /drivers/pci/intel-iommu.c
parent3b5410e735b093060b96664230c6f9f4fe80b251 (diff)
downloadlinux-d9630fe941769dd050fbc38fbbac20a708ab9461.tar.gz
Add global iommu list
Signed-off-by: Weidong Han <weidong.han@intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r--drivers/pci/intel-iommu.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 22ad8851b3e0..d2ffa7a6d723 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -57,6 +57,9 @@
 #define DMA_32BIT_PFN		IOVA_PFN(DMA_32BIT_MASK)
 #define DMA_64BIT_PFN		IOVA_PFN(DMA_64BIT_MASK)
 
+/* global iommu list, set NULL for ignored DMAR units */
+static struct intel_iommu **g_iommus;
+
 /*
  * 0: Present
  * 1-11: Reserved
@@ -1153,6 +1156,17 @@ void free_dmar_iommu(struct intel_iommu *iommu)
 	kfree(iommu->domains);
 	kfree(iommu->domain_ids);
 
+	g_iommus[iommu->seq_id] = NULL;
+
+	/* if all iommus are freed, free g_iommus */
+	for (i = 0; i < g_num_of_iommus; i++) {
+		if (g_iommus[i])
+			break;
+	}
+
+	if (i == g_num_of_iommus)
+		kfree(g_iommus);
+
 	/* free context mapping */
 	free_context_table(iommu);
 }
@@ -1794,9 +1808,18 @@ static int __init init_dmars(void)
 		 */
 	}
 
+	g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
+			GFP_KERNEL);
+	if (!g_iommus) {
+		printk(KERN_ERR "Allocating global iommu array failed\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
 	deferred_flush = kzalloc(g_num_of_iommus *
 		sizeof(struct deferred_flush_tables), GFP_KERNEL);
 	if (!deferred_flush) {
+		kfree(g_iommus);
 		ret = -ENOMEM;
 		goto error;
 	}
@@ -1806,6 +1829,7 @@ static int __init init_dmars(void)
 			continue;
 
 		iommu = drhd->iommu;
+		g_iommus[iommu->seq_id] = iommu;
 
 		ret = iommu_init_domains(iommu);
 		if (ret)
@@ -1918,6 +1942,7 @@ error:
 		iommu = drhd->iommu;
 		free_iommu(iommu);
 	}
+	kfree(g_iommus);
 	return ret;
 }