+++ /dev/null
-From: Suresh Siddha <suresh.b.siddha@intel.com>
-Subject: x64, x2apic/intr-remap: fix the need for sequential array allocation of iommus
-References: fate #303948 and fate #303984
-Patch-Mainline: queued for .28
-Commit-ID: c42d9f32443397aed2d37d37df161392e6a5862f
-
-Signed-off-by: Thomas Renninger <trenn@suse.de>
-
-Clean up the intel-iommu code related to deferred iommu flush logic. There is
-no need to allocate all the iommu's as a sequential array.
-
-This will be used later in the interrupt-remapping patch series to
-allocate iommu much early and individually for each device remapping
-hardware unit.
-
-Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
-Cc: akpm@linux-foundation.org
-Cc: arjan@linux.intel.com
-Cc: andi@firstfloor.org
-Cc: ebiederm@xmission.com
-Cc: jbarnes@virtuousgeek.org
-Cc: steiner@sgi.com
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-
----
- drivers/pci/dmar.c | 11 +++++++++--
- drivers/pci/intel-iommu.c | 23 +++++++----------------
- drivers/pci/intel-iommu.h | 4 ++--
- 3 files changed, 18 insertions(+), 20 deletions(-)
-
---- a/drivers/pci/dmar.c
-+++ b/drivers/pci/dmar.c
-@@ -375,11 +375,18 @@ int __init early_dmar_detect(void)
- return (ACPI_SUCCESS(status) ? 1 : 0);
- }
-
--struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
-- struct dmar_drhd_unit *drhd)
-+struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
- {
-+ struct intel_iommu *iommu;
- int map_size;
- u32 ver;
-+ static int iommu_allocated = 0;
-+
-+ iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
-+ if (!iommu)
-+ return NULL;
-+
-+ iommu->seq_id = iommu_allocated++;
-
- iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
- if (!iommu->reg) {
---- a/drivers/pci/intel-iommu.c
-+++ b/drivers/pci/intel-iommu.c
-@@ -58,8 +58,6 @@ static void flush_unmaps_timeout(unsigne
-
- DEFINE_TIMER(unmap_timer, flush_unmaps_timeout, 0, 0);
-
--static struct intel_iommu *g_iommus;
--
- #define HIGH_WATER_MARK 250
- struct deferred_flush_tables {
- int next;
-@@ -1651,8 +1649,6 @@ int __init init_dmars(void)
- * endfor
- */
- for_each_drhd_unit(drhd) {
-- if (drhd->ignored)
-- continue;
- g_num_of_iommus++;
- /*
- * lock not needed as this is only incremented in the single
-@@ -1661,12 +1657,6 @@ int __init init_dmars(void)
- */
- }
-
-- g_iommus = kzalloc(g_num_of_iommus * sizeof(*iommu), GFP_KERNEL);
-- if (!g_iommus) {
-- ret = -ENOMEM;
-- goto error;
-- }
--
- deferred_flush = kzalloc(g_num_of_iommus *
- sizeof(struct deferred_flush_tables), GFP_KERNEL);
- if (!deferred_flush) {
-@@ -1674,12 +1664,10 @@ int __init init_dmars(void)
- goto error;
- }
-
-- i = 0;
- for_each_drhd_unit(drhd) {
- if (drhd->ignored)
- continue;
-- iommu = alloc_iommu(&g_iommus[i], drhd);
-- i++;
-+ iommu = alloc_iommu(drhd);
- if (!iommu) {
- ret = -ENOMEM;
- goto error;
-@@ -1771,7 +1759,6 @@ error:
- iommu = drhd->iommu;
- free_iommu(iommu);
- }
-- kfree(g_iommus);
- return ret;
- }
-
-@@ -1928,7 +1915,10 @@ static void flush_unmaps(void)
- /* just flush them all */
- for (i = 0; i < g_num_of_iommus; i++) {
- if (deferred_flush[i].next) {
-- iommu_flush_iotlb_global(&g_iommus[i], 0);
-+ struct intel_iommu *iommu =
-+ deferred_flush[i].domain[0]->iommu;
-+
-+ iommu_flush_iotlb_global(iommu, 0);
- for (j = 0; j < deferred_flush[i].next; j++) {
- __free_iova(&deferred_flush[i].domain[j]->iovad,
- deferred_flush[i].iova[j]);
-@@ -1958,7 +1948,8 @@ static void add_unmap(struct dmar_domain
- if (list_size == HIGH_WATER_MARK)
- flush_unmaps();
-
-- iommu_id = dom->iommu - g_iommus;
-+ iommu_id = dom->iommu->seq_id;
-+
- next = deferred_flush[iommu_id].next;
- deferred_flush[iommu_id].domain[next] = dom;
- deferred_flush[iommu_id].iova[next] = iova;
---- a/drivers/pci/intel-iommu.h
-+++ b/drivers/pci/intel-iommu.h
-@@ -182,6 +182,7 @@ struct intel_iommu {
- int seg;
- u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
- spinlock_t register_lock; /* protect register handling */
-+ int seq_id; /* sequence id of the iommu */
-
- #ifdef CONFIG_DMAR
- unsigned long *domain_ids; /* bitmap of domains */
-@@ -198,8 +199,7 @@ struct intel_iommu {
-
- extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
-
--extern struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
-- struct dmar_drhd_unit *drhd);
-+extern struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd);
- extern void free_iommu(struct intel_iommu *iommu);
-
- #endif