int free_irte(int irq) { int index, i; struct irte *irte; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } iommu = irq_iommu->iommu; index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; if (!irq_iommu->sub_handle) { for (i = 0; i < (1 << irq_iommu->irte_mask); i++) set_64bit((unsigned long *)irte, 0); qi_flush_iec(iommu, index, irq_iommu->irte_mask); } irq_iommu->iommu = NULL; irq_iommu->irte_index = 0; irq_iommu->sub_handle = 0; irq_iommu->irte_mask = 0; spin_unlock(&irq_2_ir_lock); return 0; }
int modify_irte(int irq, struct irte *irte_modified) { int rc; int index; struct irte *irte; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; unsigned long flags; spin_lock_irqsave(&irq_2_ir_lock, flags); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); return -1; } iommu = irq_iommu->iommu; index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; set_64bit((unsigned long *)&irte->low, irte_modified->low); set_64bit((unsigned long *)&irte->high, irte_modified->high); __iommu_flush_cache(iommu, irte, sizeof(*irte)); rc = qi_flush_iec(iommu, index, 0); spin_unlock_irqrestore(&irq_2_ir_lock, flags); return rc; }
int modify_irte(int irq, struct irte *irte_modified) { int index; struct irte *irte; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } iommu = irq_iommu->iommu; index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); __iommu_flush_cache(iommu, irte, sizeof(*irte)); qi_flush_iec(iommu, index, 0); spin_unlock(&irq_2_ir_lock); return 0; }
int map_irq_to_irte_handle(int irq, u16 *sub_handle) { int index; struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } *sub_handle = irq_iommu->sub_handle; index = irq_iommu->irte_index; spin_unlock(&irq_2_ir_lock); return index; }
int map_irq_to_irte_handle(int irq, u16 *sub_handle) { int index; struct irq_2_iommu *irq_iommu; unsigned long flags; spin_lock_irqsave(&irq_2_ir_lock, flags); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); return -1; } *sub_handle = irq_iommu->sub_handle; index = irq_iommu->irte_index; spin_unlock_irqrestore(&irq_2_ir_lock, flags); return index; }
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) { struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } irq_iommu->iommu = NULL; irq_iommu->irte_index = 0; irq_iommu->sub_handle = 0; irq_2_iommu(irq)->irte_mask = 0; spin_unlock(&irq_2_ir_lock); return 0; }
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) { struct irq_2_iommu *irq_iommu; unsigned long flags; spin_lock_irqsave(&irq_2_ir_lock, flags); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); return -1; } irq_iommu->iommu = NULL; irq_iommu->irte_index = 0; irq_iommu->sub_handle = 0; irq_2_iommu(irq)->irte_mask = 0; spin_unlock_irqrestore(&irq_2_ir_lock, flags); return 0; }
int get_irte(int irq, struct irte *entry) { int index; struct irq_2_iommu *irq_iommu; if (!entry) return -1; spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } index = irq_iommu->irte_index + irq_iommu->sub_handle; *entry = *(irq_iommu->iommu->ir_table->base + index); spin_unlock(&irq_2_ir_lock); return 0; }
int get_irte(int irq, struct irte *entry) { int index; struct irq_2_iommu *irq_iommu; unsigned long flags; if (!entry) return -1; spin_lock_irqsave(&irq_2_ir_lock, flags); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); return -1; } index = irq_iommu->irte_index + irq_iommu->sub_handle; *entry = *(irq_iommu->iommu->ir_table->base + index); spin_unlock_irqrestore(&irq_2_ir_lock, flags); return 0; }
int flush_irte(int irq) { int index; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } iommu = irq_iommu->iommu; index = irq_iommu->irte_index + irq_iommu->sub_handle; qi_flush_iec(iommu, index, irq_iommu->irte_mask); spin_unlock(&irq_2_ir_lock); return 0; }
int free_irte(int irq) { int rc = 0; struct irq_2_iommu *irq_iommu; unsigned long flags; spin_lock_irqsave(&irq_2_ir_lock, flags); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); return -1; } rc = clear_entries(irq_iommu); irq_iommu->iommu = NULL; irq_iommu->irte_index = 0; irq_iommu->sub_handle = 0; irq_iommu->irte_mask = 0; spin_unlock_irqrestore(&irq_2_ir_lock, flags); return rc; }
int flush_irte(int irq) { int rc; int index; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; unsigned long flags; spin_lock_irqsave(&irq_2_ir_lock, flags); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); return -1; } iommu = irq_iommu->iommu; index = irq_iommu->irte_index + irq_iommu->sub_handle; rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); spin_unlock_irqrestore(&irq_2_ir_lock, flags); return rc; }
int irq_remapped(int irq) { return valid_irq_2_iommu(irq) != NULL; }