iommu/vt-d: Convert MSI remapping setup to remap_ops
This patch introduces remapping-ops for setting ups MSI interrupts. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
@@ -3070,54 +3070,34 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
|
||||
dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
|
||||
|
||||
if (irq_remapped(cfg)) {
|
||||
struct irte irte;
|
||||
int ir_index;
|
||||
u16 sub_handle;
|
||||
|
||||
ir_index = map_irq_to_irte_handle(irq, &sub_handle);
|
||||
BUG_ON(ir_index == -1);
|
||||
|
||||
prepare_irte(&irte, cfg->vector, dest);
|
||||
|
||||
/* Set source-id of interrupt request */
|
||||
if (pdev)
|
||||
set_msi_sid(&irte, pdev);
|
||||
else
|
||||
set_hpet_sid(&irte, hpet_id);
|
||||
|
||||
modify_irte(irq, &irte);
|
||||
|
||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||
msg->data = sub_handle;
|
||||
msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT |
|
||||
MSI_ADDR_IR_SHV |
|
||||
MSI_ADDR_IR_INDEX1(ir_index) |
|
||||
MSI_ADDR_IR_INDEX2(ir_index);
|
||||
} else {
|
||||
if (x2apic_enabled())
|
||||
msg->address_hi = MSI_ADDR_BASE_HI |
|
||||
MSI_ADDR_EXT_DEST_ID(dest);
|
||||
else
|
||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||
|
||||
msg->address_lo =
|
||||
MSI_ADDR_BASE_LO |
|
||||
((apic->irq_dest_mode == 0) ?
|
||||
MSI_ADDR_DEST_MODE_PHYSICAL:
|
||||
MSI_ADDR_DEST_MODE_LOGICAL) |
|
||||
((apic->irq_delivery_mode != dest_LowestPrio) ?
|
||||
MSI_ADDR_REDIRECTION_CPU:
|
||||
MSI_ADDR_REDIRECTION_LOWPRI) |
|
||||
MSI_ADDR_DEST_ID(dest);
|
||||
|
||||
msg->data =
|
||||
MSI_DATA_TRIGGER_EDGE |
|
||||
MSI_DATA_LEVEL_ASSERT |
|
||||
((apic->irq_delivery_mode != dest_LowestPrio) ?
|
||||
MSI_DATA_DELIVERY_FIXED:
|
||||
MSI_DATA_DELIVERY_LOWPRI) |
|
||||
MSI_DATA_VECTOR(cfg->vector);
|
||||
intr_compose_msi_msg(pdev, irq, dest, msg, hpet_id);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (x2apic_enabled())
|
||||
msg->address_hi = MSI_ADDR_BASE_HI |
|
||||
MSI_ADDR_EXT_DEST_ID(dest);
|
||||
else
|
||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||
|
||||
msg->address_lo =
|
||||
MSI_ADDR_BASE_LO |
|
||||
((apic->irq_dest_mode == 0) ?
|
||||
MSI_ADDR_DEST_MODE_PHYSICAL:
|
||||
MSI_ADDR_DEST_MODE_LOGICAL) |
|
||||
((apic->irq_delivery_mode != dest_LowestPrio) ?
|
||||
MSI_ADDR_REDIRECTION_CPU:
|
||||
MSI_ADDR_REDIRECTION_LOWPRI) |
|
||||
MSI_ADDR_DEST_ID(dest);
|
||||
|
||||
msg->data =
|
||||
MSI_DATA_TRIGGER_EDGE |
|
||||
MSI_DATA_LEVEL_ASSERT |
|
||||
((apic->irq_delivery_mode != dest_LowestPrio) ?
|
||||
MSI_DATA_DELIVERY_FIXED:
|
||||
MSI_DATA_DELIVERY_LOWPRI) |
|
||||
MSI_DATA_VECTOR(cfg->vector);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3160,33 +3140,6 @@ static struct irq_chip msi_chip = {
|
||||
.irq_retrigger = ioapic_retrigger_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
* Map the PCI dev to the corresponding remapping hardware unit
|
||||
* and allocate 'nvec' consecutive interrupt-remapping table entries
|
||||
* in it.
|
||||
*/
|
||||
static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
|
||||
{
|
||||
struct intel_iommu *iommu;
|
||||
int index;
|
||||
|
||||
iommu = map_dev_to_ir(dev);
|
||||
if (!iommu) {
|
||||
printk(KERN_ERR
|
||||
"Unable to map PCI %s to iommu\n", pci_name(dev));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
index = alloc_irte(iommu, irq, nvec);
|
||||
if (index < 0) {
|
||||
printk(KERN_ERR
|
||||
"Unable to allocate %d IRTE for PCI %s\n", nvec,
|
||||
pci_name(dev));
|
||||
return -ENOSPC;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
|
||||
{
|
||||
struct irq_chip *chip = &msi_chip;
|
||||
@@ -3217,7 +3170,6 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
int node, ret, sub_handle, index = 0;
|
||||
unsigned int irq, irq_want;
|
||||
struct msi_desc *msidesc;
|
||||
struct intel_iommu *iommu = NULL;
|
||||
|
||||
/* x86 doesn't support multiple MSI yet */
|
||||
if (type == PCI_CAP_ID_MSI && nvec > 1)
|
||||
@@ -3239,23 +3191,15 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
* allocate the consecutive block of IRTE's
|
||||
* for 'nvec'
|
||||
*/
|
||||
index = msi_alloc_irte(dev, irq, nvec);
|
||||
index = intr_msi_alloc_irq(dev, irq, nvec);
|
||||
if (index < 0) {
|
||||
ret = index;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
iommu = map_dev_to_ir(dev);
|
||||
if (!iommu) {
|
||||
ret = -ENOENT;
|
||||
ret = intr_msi_setup_irq(dev, irq, index, sub_handle);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* setup the mapping between the irq and the IRTE
|
||||
* base index, the sub_handle pointing to the
|
||||
* appropriate interrupt remap table entry.
|
||||
*/
|
||||
set_irte_irq(irq, iommu, index, sub_handle);
|
||||
}
|
||||
no_ir:
|
||||
ret = setup_msi_irq(dev, msidesc, irq);
|
||||
@@ -3374,14 +3318,7 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
|
||||
int ret;
|
||||
|
||||
if (intr_remapping_enabled) {
|
||||
struct intel_iommu *iommu = map_hpet_to_ir(id);
|
||||
int index;
|
||||
|
||||
if (!iommu)
|
||||
return -1;
|
||||
|
||||
index = alloc_irte(iommu, irq, 1);
|
||||
if (index < 0)
|
||||
if (!intr_setup_hpet_msi(irq, id))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user