static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); u16 index, start_index; unsigned int mask = 0; unsigned long flags; int i; if (!count || !irq_iommu) return -1; /* * start the IRTE search from index 0. */ index = start_index = 0; if (count > 1) { count = __roundup_pow_of_two(count); mask = ilog2(count); } if (mask > ecap_max_handle_mask(iommu->ecap)) { printk(KERN_ERR "Requested mask %x exceeds the max invalidation handle" " mask value %Lx\n", mask, ecap_max_handle_mask(iommu->ecap)); return -1; } 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; 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; }
static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); struct irq_cfg *cfg = irq_get_chip_data(irq); unsigned int mask = 0; unsigned long flags; int index; if (!count || !irq_iommu) return -1; if (count > 1) { count = __roundup_pow_of_two(count); mask = ilog2(count); } if (mask > ecap_max_handle_mask(iommu->ecap)) { printk(KERN_ERR "Requested mask %x exceeds the max invalidation handle" " mask value %Lx\n", mask, ecap_max_handle_mask(iommu->ecap)); return -1; } raw_spin_lock_irqsave(&irq_2_ir_lock, flags); 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; }
int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu; u16 index, start_index; unsigned int mask = 0; int i; if (!count) return -1; #ifndef CONFIG_SPARSE_IRQ /* protect irq_2_iommu_alloc later */ if (irq >= nr_irqs) return -1; #endif /* * start the IRTE search from index 0. */ index = start_index = 0; if (count > 1) { count = __roundup_pow_of_two(count); mask = ilog2(count); } if (mask > ecap_max_handle_mask(iommu->ecap)) { printk(KERN_ERR "Requested mask %x exceeds the max invalidation handle" " mask value %Lx\n", mask, ecap_max_handle_mask(iommu->ecap)); return -1; } spin_lock(&irq_2_ir_lock); 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) { spin_unlock(&irq_2_ir_lock); 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; irq_iommu = irq_2_iommu_alloc(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); printk(KERN_ERR "can't allocate irq_2_iommu\n"); return -1; } irq_iommu->iommu = iommu; irq_iommu->irte_index = index; irq_iommu->sub_handle = 0; irq_iommu->irte_mask = mask; spin_unlock(&irq_2_ir_lock); return index; }