iommu/vt-d, trivial: refine support of 64bit guest address
[deliverable/linux.git] / drivers / iommu / intel_irq_remapping.c
index bab10b1002fbf04bae1fe8e2b36cbb6f280dea51..3aa9b5c347e4e457d33abfafa5e6a63fda156e82 100644 (file)
@@ -46,7 +46,7 @@ static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
        return cfg ? &cfg->irq_2_iommu : NULL;
 }
 
-int get_irte(int irq, struct irte *entry)
+static int get_irte(int irq, struct irte *entry)
 {
        struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
        unsigned long flags;
@@ -72,7 +72,6 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
        u16 index, start_index;
        unsigned int mask = 0;
        unsigned long flags;
-       int i;
 
        if (!count || !irq_iommu)
                return -1;
@@ -96,32 +95,17 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
        }
 
        raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
-       do {
-               for (i = index; i < index + count; i++)
-                       if  (table->base[i].present)
-                               break;
-               /* empty index found */
-               if (i == index + count)
-                       break;
-
-               index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
-
-               if (index == start_index) {
-                       raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
-                       printk(KERN_ERR "can't allocate an IRTE\n");
-                       return -1;
-               }
-       } while (1);
-
-       for (i = index; i < index + count; i++)
-               table->base[i].present = 1;
-
-       cfg->remapped = 1;
-       irq_iommu->iommu = iommu;
-       irq_iommu->irte_index =  index;
-       irq_iommu->sub_handle = 0;
-       irq_iommu->irte_mask = mask;
-
+       index = bitmap_find_free_region(table->bitmap,
+                                       INTR_REMAP_TABLE_ENTRIES, mask);
+       if (index < 0) {
+               pr_warn("IR%d: can't allocate an IRTE\n", iommu->seq_id);
+       } else {
+               cfg->remapped = 1;
+               irq_iommu->iommu = iommu;
+               irq_iommu->irte_index =  index;
+               irq_iommu->sub_handle = 0;
+               irq_iommu->irte_mask = mask;
+       }
        raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
        return index;
@@ -254,6 +238,8 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
                set_64bit(&entry->low, 0);
                set_64bit(&entry->high, 0);
        }
+       bitmap_release_region(iommu->ir_table->bitmap, index,
+                             irq_iommu->irte_mask);
 
        return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
 }
@@ -453,6 +439,7 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
 {
        struct ir_table *ir_table;
        struct page *pages;
+       unsigned long *bitmap;
 
        ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table),
                                             GFP_ATOMIC);
@@ -464,13 +451,23 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
                                 INTR_REMAP_PAGE_ORDER);
 
        if (!pages) {
-               printk(KERN_ERR "failed to allocate pages of order %d\n",
-                      INTR_REMAP_PAGE_ORDER);
+               pr_err("IR%d: failed to allocate pages of order %d\n",
+                      iommu->seq_id, INTR_REMAP_PAGE_ORDER);
                kfree(iommu->ir_table);
                return -ENOMEM;
        }
 
+       bitmap = kcalloc(BITS_TO_LONGS(INTR_REMAP_TABLE_ENTRIES),
+                        sizeof(long), GFP_ATOMIC);
+       if (bitmap == NULL) {
+               pr_err("IR%d: failed to allocate bitmap\n", iommu->seq_id);
+               __free_pages(pages, INTR_REMAP_PAGE_ORDER);
+               kfree(ir_table);
+               return -ENOMEM;
+       }
+
        ir_table->base = page_address(pages);
+       ir_table->bitmap = bitmap;
 
        iommu_set_irq_remapping(iommu, mode);
        return 0;
@@ -807,7 +804,7 @@ int __init parse_ioapics_under_ir(void)
        return 1;
 }
 
-int __init ir_dev_scope_init(void)
+static int __init ir_dev_scope_init(void)
 {
        if (!irq_remapping_enabled)
                return 0;
This page took 0.02632 seconds and 5 git commands to generate.