VT-d: include IOMMU interrupt information in 'M' debug key output Signed-off-by: Jan Beulich --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1008,6 +1008,7 @@ static void dma_msi_unmask(struct irq_de spin_lock_irqsave(&iommu->register_lock, flags); dmar_writel(iommu->reg, DMAR_FECTL_REG, 0); spin_unlock_irqrestore(&iommu->register_lock, flags); + iommu->msi.msi_attrib.masked = 0; } static void dma_msi_mask(struct irq_desc *desc) @@ -1019,6 +1020,7 @@ static void dma_msi_mask(struct irq_desc spin_lock_irqsave(&iommu->register_lock, flags); dmar_writel(iommu->reg, DMAR_FECTL_REG, DMA_FECTL_IM); spin_unlock_irqrestore(&iommu->register_lock, flags); + iommu->msi.msi_attrib.masked = 1; } static unsigned int dma_msi_startup(struct irq_desc *desc) @@ -1059,6 +1061,7 @@ static void dma_msi_set_affinity(struct msg.address_hi = dest & 0xFFFFFF00; msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; msg.address_lo |= MSI_ADDR_DEST_ID(dest & 0xff); + iommu->msi.msg = msg; spin_lock_irqsave(&iommu->register_lock, flags); dmar_writel(iommu->reg, DMAR_FEDATA_REG, msg.data); @@ -1082,6 +1085,8 @@ static int __init iommu_set_interrupt(st { int irq, ret; struct acpi_rhsa_unit *rhsa = drhd_to_rhsa(drhd); + struct iommu *iommu = drhd->iommu; + struct irq_desc *desc; irq = create_irq(rhsa ? pxm_to_node(rhsa->proximity_domain) : NUMA_NO_NODE); @@ -1091,17 +1096,24 @@ static int __init iommu_set_interrupt(st return -EINVAL; } - irq_desc[irq].handler = &dma_msi_type; - ret = request_irq(irq, iommu_page_fault, 0, "dmar", drhd->iommu); + desc = irq_to_desc(irq); + desc->handler = &dma_msi_type; + ret = request_irq(irq, iommu_page_fault, 0, "dmar", iommu); if ( ret ) { - irq_desc[irq].handler = &no_irq_type; + desc->handler = &no_irq_type; destroy_irq(irq); dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: can't request irq\n"); return ret; } - return irq; + iommu->msi.irq = irq; + iommu->msi.msi_attrib.pos = MSI_TYPE_IOMMU; + iommu->msi.msi_attrib.maskbit = 1; + iommu->msi.msi_attrib.is_64 = 1; + desc->msi_desc = &iommu->msi; + + return 0; } int __init iommu_alloc(struct acpi_drhd_unit *drhd) @@ -1121,7 +1133,7 @@ int __init iommu_alloc(struct acpi_drhd_ if ( iommu == NULL ) return -ENOMEM; - iommu->irq = -1; /* No irq assigned yet. */ + iommu->msi.irq = -1; /* No irq assigned yet. */ iommu->intel = alloc_intel_iommu(); if ( iommu->intel == NULL ) @@ -1218,8 +1230,8 @@ void __init iommu_free(struct acpi_drhd_ xfree(iommu->domid_map); free_intel_iommu(iommu->intel); - if ( iommu->irq >= 0 ) - destroy_irq(iommu->irq); + if ( iommu->msi.irq >= 0 ) + destroy_irq(iommu->msi.irq); xfree(iommu); } @@ -1976,7 +1988,7 @@ static int init_vtd_hw(void) iommu = drhd->iommu; - desc = irq_to_desc(iommu->irq); + desc = irq_to_desc(iommu->msi.irq); dma_msi_set_affinity(desc, desc->arch.cpu_mask); clear_fault_bits(iommu); @@ -2122,12 +2134,11 @@ int __init intel_vtd_setup(void) iommu_hap_pt_share = 0; ret = iommu_set_interrupt(drhd); - if ( ret < 0 ) + if ( ret ) { dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n"); goto error; } - iommu->irq = ret; } softirq_tasklet_init(&vtd_fault_tasklet, do_iommu_page_fault, 0); --- a/xen/drivers/passthrough/vtd/iommu.h +++ b/xen/drivers/passthrough/vtd/iommu.h @@ -21,6 +21,7 @@ #define _INTEL_IOMMU_H_ #include +#include /* * Intel IOMMU register specification per version 1.0 public spec. @@ -520,7 +521,7 @@ struct iommu { spinlock_t lock; /* protect context, domain ids */ spinlock_t register_lock; /* protect iommu register handling */ u64 root_maddr; /* root entry machine address */ - int irq; + struct msi_desc msi; struct intel_iommu *intel; unsigned long *domid_bitmap; /* domain id bitmap */ u16 *domid_map; /* domain id mapping array */