aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/dmar.c11
-rw-r--r--drivers/pci/intel-iommu.c24
-rw-r--r--drivers/pci/intel-iommu.h4
3 files changed, 18 insertions, 21 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index c00e387f5b7..1a59423a8ed 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -377,11 +377,18 @@ int __init early_dmar_detect(void)
377 return (ACPI_SUCCESS(status) ? 1 : 0); 377 return (ACPI_SUCCESS(status) ? 1 : 0);
378} 378}
379 379
380struct intel_iommu *alloc_iommu(struct intel_iommu *iommu, 380struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
381 struct dmar_drhd_unit *drhd)
382{ 381{
382 struct intel_iommu *iommu;
383 int map_size; 383 int map_size;
384 u32 ver; 384 u32 ver;
385 static int iommu_allocated = 0;
386
387 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
388 if (!iommu)
389 return NULL;
390
391 iommu->seq_id = iommu_allocated++;
385 392
386 iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K); 393 iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
387 if (!iommu->reg) { 394 if (!iommu->reg) {
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 1c0270d3e2e..4d59a6a1f4d 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -58,8 +58,6 @@ static void flush_unmaps_timeout(unsigned long data);
58 58
59DEFINE_TIMER(unmap_timer, flush_unmaps_timeout, 0, 0); 59DEFINE_TIMER(unmap_timer, flush_unmaps_timeout, 0, 0);
60 60
61static struct intel_iommu *g_iommus;
62
63#define HIGH_WATER_MARK 250 61#define HIGH_WATER_MARK 250
64struct deferred_flush_tables { 62struct deferred_flush_tables {
65 int next; 63 int next;
@@ -1649,8 +1647,6 @@ int __init init_dmars(void)
1649 * endfor 1647 * endfor
1650 */ 1648 */
1651 for_each_drhd_unit(drhd) { 1649 for_each_drhd_unit(drhd) {
1652 if (drhd->ignored)
1653 continue;
1654 g_num_of_iommus++; 1650 g_num_of_iommus++;
1655 /* 1651 /*
1656 * lock not needed as this is only incremented in the single 1652 * lock not needed as this is only incremented in the single
@@ -1659,26 +1655,17 @@ int __init init_dmars(void)
1659 */ 1655 */
1660 } 1656 }
1661 1657
1662 g_iommus = kzalloc(g_num_of_iommus * sizeof(*iommu), GFP_KERNEL);
1663 if (!g_iommus) {
1664 ret = -ENOMEM;
1665 goto error;
1666 }
1667
1668 deferred_flush = kzalloc(g_num_of_iommus * 1658 deferred_flush = kzalloc(g_num_of_iommus *
1669 sizeof(struct deferred_flush_tables), GFP_KERNEL); 1659 sizeof(struct deferred_flush_tables), GFP_KERNEL);
1670 if (!deferred_flush) { 1660 if (!deferred_flush) {
1671 kfree(g_iommus);
1672 ret = -ENOMEM; 1661 ret = -ENOMEM;
1673 goto error; 1662 goto error;
1674 } 1663 }
1675 1664
1676 i = 0;
1677 for_each_drhd_unit(drhd) { 1665 for_each_drhd_unit(drhd) {
1678 if (drhd->ignored) 1666 if (drhd->ignored)
1679 continue; 1667 continue;
1680 iommu = alloc_iommu(&g_iommus[i], drhd); 1668 iommu = alloc_iommu(drhd);
1681 i++;
1682 if (!iommu) { 1669 if (!iommu) {
1683 ret = -ENOMEM; 1670 ret = -ENOMEM;
1684 goto error; 1671 goto error;
@@ -1770,7 +1757,6 @@ error:
1770 iommu = drhd->iommu; 1757 iommu = drhd->iommu;
1771 free_iommu(iommu); 1758 free_iommu(iommu);
1772 } 1759 }
1773 kfree(g_iommus);
1774 return ret; 1760 return ret;
1775} 1761}
1776 1762
@@ -1927,7 +1913,10 @@ static void flush_unmaps(void)
1927 /* just flush them all */ 1913 /* just flush them all */
1928 for (i = 0; i < g_num_of_iommus; i++) { 1914 for (i = 0; i < g_num_of_iommus; i++) {
1929 if (deferred_flush[i].next) { 1915 if (deferred_flush[i].next) {
1930 iommu_flush_iotlb_global(&g_iommus[i], 0); 1916 struct intel_iommu *iommu =
1917 deferred_flush[i].domain[0]->iommu;
1918
1919 iommu_flush_iotlb_global(iommu, 0);
1931 for (j = 0; j < deferred_flush[i].next; j++) { 1920 for (j = 0; j < deferred_flush[i].next; j++) {
1932 __free_iova(&deferred_flush[i].domain[j]->iovad, 1921 __free_iova(&deferred_flush[i].domain[j]->iovad,
1933 deferred_flush[i].iova[j]); 1922 deferred_flush[i].iova[j]);
@@ -1957,7 +1946,8 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
1957 if (list_size == HIGH_WATER_MARK) 1946 if (list_size == HIGH_WATER_MARK)
1958 flush_unmaps(); 1947 flush_unmaps();
1959 1948
1960 iommu_id = dom->iommu - g_iommus; 1949 iommu_id = dom->iommu->seq_id;
1950
1961 next = deferred_flush[iommu_id].next; 1951 next = deferred_flush[iommu_id].next;
1962 deferred_flush[iommu_id].domain[next] = dom; 1952 deferred_flush[iommu_id].domain[next] = dom;
1963 deferred_flush[iommu_id].iova[next] = iova; 1953 deferred_flush[iommu_id].iova[next] = iova;
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h
index 9e5e98c76c0..75c63f65b3f 100644
--- a/drivers/pci/intel-iommu.h
+++ b/drivers/pci/intel-iommu.h
@@ -182,6 +182,7 @@ struct intel_iommu {
182 int seg; 182 int seg;
183 u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ 183 u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
184 spinlock_t register_lock; /* protect register handling */ 184 spinlock_t register_lock; /* protect register handling */
185 int seq_id; /* sequence id of the iommu */
185 186
186#ifdef CONFIG_DMAR 187#ifdef CONFIG_DMAR
187 unsigned long *domain_ids; /* bitmap of domains */ 188 unsigned long *domain_ids; /* bitmap of domains */
@@ -198,8 +199,7 @@ struct intel_iommu {
198 199
199extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev); 200extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
200 201
201extern struct intel_iommu *alloc_iommu(struct intel_iommu *iommu, 202extern struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd);
202 struct dmar_drhd_unit *drhd);
203extern void free_iommu(struct intel_iommu *iommu); 203extern void free_iommu(struct intel_iommu *iommu);
204 204
205#endif 205#endif