|
@@ -3993,22 +3993,6 @@ out:
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
-static int get_irte(u16 devid, int index, union irte *irte)
|
|
|
-{
|
|
|
- struct irq_remap_table *table;
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- table = get_irq_table(devid, false);
|
|
|
- if (!table)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- spin_lock_irqsave(&table->lock, flags);
|
|
|
- irte->val = table->table[index];
|
|
|
- spin_unlock_irqrestore(&table->lock, flags);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int modify_irte(u16 devid, int index, union irte irte)
|
|
|
{
|
|
|
struct irq_remap_table *table;
|
|
@@ -4055,131 +4039,6 @@ static void free_irte(u16 devid, int index)
|
|
|
iommu_completion_wait(iommu);
|
|
|
}
|
|
|
|
|
|
-static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
|
|
|
- unsigned int destination, int vector,
|
|
|
- struct io_apic_irq_attr *attr)
|
|
|
-{
|
|
|
- struct irq_remap_table *table;
|
|
|
- struct irq_2_irte *irte_info;
|
|
|
- struct irq_cfg *cfg;
|
|
|
- union irte irte;
|
|
|
- int ioapic_id;
|
|
|
- int index;
|
|
|
- int devid;
|
|
|
- int ret;
|
|
|
-
|
|
|
- cfg = irq_cfg(irq);
|
|
|
- if (!cfg)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- irte_info = &cfg->irq_2_irte;
|
|
|
- ioapic_id = mpc_ioapic_id(attr->ioapic);
|
|
|
- devid = get_ioapic_devid(ioapic_id);
|
|
|
-
|
|
|
- if (devid < 0)
|
|
|
- return devid;
|
|
|
-
|
|
|
- table = get_irq_table(devid, true);
|
|
|
- if (table == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- index = attr->ioapic_pin;
|
|
|
-
|
|
|
- /* Setup IRQ remapping info */
|
|
|
- cfg->remapped = 1;
|
|
|
- irte_info->devid = devid;
|
|
|
- irte_info->index = index;
|
|
|
-
|
|
|
- /* Setup IRTE for IOMMU */
|
|
|
- irte.val = 0;
|
|
|
- irte.fields.vector = vector;
|
|
|
- irte.fields.int_type = apic->irq_delivery_mode;
|
|
|
- irte.fields.destination = destination;
|
|
|
- irte.fields.dm = apic->irq_dest_mode;
|
|
|
- irte.fields.valid = 1;
|
|
|
-
|
|
|
- ret = modify_irte(devid, index, irte);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- /* Setup IOAPIC entry */
|
|
|
- memset(entry, 0, sizeof(*entry));
|
|
|
-
|
|
|
- entry->vector = index;
|
|
|
- entry->mask = 0;
|
|
|
- entry->trigger = attr->trigger;
|
|
|
- entry->polarity = attr->polarity;
|
|
|
-
|
|
|
- /*
|
|
|
- * Mask level triggered irqs.
|
|
|
- */
|
|
|
- if (attr->trigger)
|
|
|
- entry->mask = 1;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int set_affinity(struct irq_data *data, const struct cpumask *mask,
|
|
|
- bool force)
|
|
|
-{
|
|
|
- struct irq_2_irte *irte_info;
|
|
|
- unsigned int dest, irq;
|
|
|
- struct irq_cfg *cfg;
|
|
|
- union irte irte;
|
|
|
- int err;
|
|
|
-
|
|
|
- if (!config_enabled(CONFIG_SMP))
|
|
|
- return -1;
|
|
|
-
|
|
|
- cfg = irqd_cfg(data);
|
|
|
- irq = data->irq;
|
|
|
- irte_info = &cfg->irq_2_irte;
|
|
|
-
|
|
|
- if (!cpumask_intersects(mask, cpu_online_mask))
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- if (get_irte(irte_info->devid, irte_info->index, &irte))
|
|
|
- return -EBUSY;
|
|
|
-
|
|
|
- if (assign_irq_vector(irq, cfg, mask))
|
|
|
- return -EBUSY;
|
|
|
-
|
|
|
- err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest);
|
|
|
- if (err) {
|
|
|
- if (assign_irq_vector(irq, cfg, data->affinity))
|
|
|
- pr_err("AMD-Vi: Failed to recover vector for irq %d\n", irq);
|
|
|
- return err;
|
|
|
- }
|
|
|
-
|
|
|
- irte.fields.vector = cfg->vector;
|
|
|
- irte.fields.destination = dest;
|
|
|
-
|
|
|
- modify_irte(irte_info->devid, irte_info->index, irte);
|
|
|
-
|
|
|
- if (cfg->move_in_progress)
|
|
|
- send_cleanup_vector(cfg);
|
|
|
-
|
|
|
- cpumask_copy(data->affinity, mask);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int free_irq(int irq)
|
|
|
-{
|
|
|
- struct irq_2_irte *irte_info;
|
|
|
- struct irq_cfg *cfg;
|
|
|
-
|
|
|
- cfg = irq_cfg(irq);
|
|
|
- if (!cfg)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- irte_info = &cfg->irq_2_irte;
|
|
|
-
|
|
|
- free_irte(irte_info->devid, irte_info->index);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int get_devid(struct irq_alloc_info *info)
|
|
|
{
|
|
|
int devid = -1;
|
|
@@ -4252,9 +4111,6 @@ struct irq_remap_ops amd_iommu_irq_ops = {
|
|
|
.disable = amd_iommu_disable,
|
|
|
.reenable = amd_iommu_reenable,
|
|
|
.enable_faulting = amd_iommu_enable_faulting,
|
|
|
- .setup_ioapic_entry = setup_ioapic_entry,
|
|
|
- .set_affinity = set_affinity,
|
|
|
- .free_irq = free_irq,
|
|
|
.get_ir_irq_domain = get_ir_irq_domain,
|
|
|
.get_irq_domain = get_irq_domain,
|
|
|
};
|