]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86, pci: Increase the number of iommus supported to be MAX_IO_APICS
authorMike Travis <travis@sgi.com>
Fri, 10 Aug 2012 11:40:36 +0000 (04:40 -0700)
committerMaxim Uvarov <maxim.uvarov@oracle.com>
Fri, 10 Aug 2012 11:41:43 +0000 (04:41 -0700)
The number of IOMMUs supported should be the same as the number of IO APICS.
This limit comes into play when the IOMMUs are identity mapped, thus the
number of possible IOMMUs in the "static identity" (si) domain should be
this same number.

Signed-off-by: Mike Travis <travis@sgi.com>
Signed-off-by: Jack Steiner <steiner@sgi.com>
drivers/pci/intel-iommu.c

index 96dc1bf0c923d0608b7ddb0283c6cbe68252cd66..57f72fb3179973ae7c3dd49f5111a1a5c85d2be5 100644 (file)
@@ -335,10 +335,18 @@ static int hw_pass_through = 1;
 /* si_domain contains mulitple devices */
 #define DOMAIN_FLAG_STATIC_IDENTITY    (1 << 2)
 
+/* define the limit of IOMMUs supported in each domain */
+#ifdef CONFIG_X86
+#define        IOMMU_UNITS_SUPPORTED   MAX_IO_APICS
+#else
+#define        IOMMU_UNITS_SUPPORTED   64
+#endif
+
 struct dmar_domain {
        int     id;                     /* domain id */
        int     nid;                    /* node id */
-       unsigned long iommu_bmp;        /* bitmap of iommus this domain uses*/
+       DECLARE_BITMAP(iommu_bmp, IOMMU_UNITS_SUPPORTED);
+                                       /* bitmap of iommus this domain uses*/
 
        struct list_head devices;       /* all devices' list */
        struct iova_domain iovad;       /* iova's that belong to this domain */
@@ -544,7 +552,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
        BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE);
        BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
 
-       iommu_id = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+       iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
        if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
                return NULL;
 
@@ -557,7 +565,7 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
 
        domain->iommu_coherency = 1;
 
-       for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
+       for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
                if (!ecap_coherent(g_iommus[i]->ecap)) {
                        domain->iommu_coherency = 0;
                        break;
@@ -571,7 +579,7 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain)
 
        domain->iommu_snooping = 1;
 
-       for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
+       for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
                if (!ecap_sc_support(g_iommus[i]->ecap)) {
                        domain->iommu_snooping = 0;
                        break;
@@ -1307,7 +1315,7 @@ static struct dmar_domain *alloc_domain(void)
                return NULL;
 
        domain->nid = -1;
-       memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
+       memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
        domain->flags = 0;
 
        return domain;
@@ -1333,7 +1341,7 @@ static int iommu_attach_domain(struct dmar_domain *domain,
 
        domain->id = num;
        set_bit(num, iommu->domain_ids);
-       set_bit(iommu->seq_id, &domain->iommu_bmp);
+       set_bit(iommu->seq_id, domain->iommu_bmp);
        iommu->domains[num] = domain;
        spin_unlock_irqrestore(&iommu->lock, flags);
 
@@ -1358,7 +1366,7 @@ static void iommu_detach_domain(struct dmar_domain *domain,
 
        if (found) {
                clear_bit(num, iommu->domain_ids);
-               clear_bit(iommu->seq_id, &domain->iommu_bmp);
+               clear_bit(iommu->seq_id, domain->iommu_bmp);
                iommu->domains[num] = NULL;
        }
        spin_unlock_irqrestore(&iommu->lock, flags);
@@ -1500,7 +1508,7 @@ static void domain_exit(struct dmar_domain *domain)
        dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
 
        for_each_active_iommu(iommu, drhd)
-               if (test_bit(iommu->seq_id, &domain->iommu_bmp))
+               if (test_bit(iommu->seq_id, domain->iommu_bmp))
                        iommu_detach_domain(domain, iommu);
 
        free_domain_mem(domain);
@@ -1626,7 +1634,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
        spin_unlock_irqrestore(&iommu->lock, flags);
 
        spin_lock_irqsave(&domain->iommu_lock, flags);
-       if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
+       if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) {
                domain->iommu_count++;
                if (domain->iommu_count == 1)
                        domain->nid = iommu->node;
@@ -2381,12 +2389,17 @@ static int __init init_dmars(void)
         * endfor
         */
        for_each_drhd_unit(drhd) {
-               g_num_of_iommus++;
                /*
                 * lock not needed as this is only incremented in the single
                 * threaded kernel __init code path all other access are read
                 * only
                 */
+               if (g_num_of_iommus < IOMMU_UNITS_SUPPORTED)
+                       g_num_of_iommus++;
+               else
+                       printk_once(KERN_ERR, 
+                         "MAX number (%d) of IOMMUs supported exceeded\n",
+                         IOMMU_UNITS_SUPPORTED);
        }
 
        g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
@@ -3574,7 +3587,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
        if (found == 0) {
                unsigned long tmp_flags;
                spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
-               clear_bit(iommu->seq_id, &domain->iommu_bmp);
+               clear_bit(iommu->seq_id, domain->iommu_bmp);
                domain->iommu_count--;
                domain_update_iommu_cap(domain);
                spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
@@ -3618,7 +3631,7 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
                 */
                spin_lock_irqsave(&domain->iommu_lock, flags2);
                if (test_and_clear_bit(iommu->seq_id,
-                                      &domain->iommu_bmp)) {
+                                      domain->iommu_bmp)) {
                        domain->iommu_count--;
                        domain_update_iommu_cap(domain);
                }
@@ -3643,7 +3656,7 @@ static struct dmar_domain *iommu_alloc_vm_domain(void)
 
        domain->id = vm_domid++;
        domain->nid = -1;
-       memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
+       memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
        domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
 
        return domain;