--- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -207,10 +207,22 @@ static void read_msi_msg(struct msi_desc static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) { + if(!(msg->data & MSI_DATA_VECTOR_MASK) || !(msg->data & MSI_DATA_LEVEL_ASSERT)//temp + || (msg->data & MSI_DATA_DELIVERY_MODE_MASK) > MSI_DATA_DELIVERY_LOWPRI) {//temp + printk("MSI: addr=%08x%08x data=%08x dest=%08x bogus!\n", msg->address_hi, msg->address_lo, msg->data, msg->dest32); + dump_execution_state(); + } entry->msg = *msg; if ( iommu_enabled ) + { + ASSERT(msg != &entry->msg); iommu_update_ire_from_msi(entry, msg); + if(!(entry->msg.data & MSI_DATA_VECTOR_MASK) || !(entry->msg.data & MSI_DATA_LEVEL_ASSERT)//temp + || (entry->msg.data & MSI_DATA_DELIVERY_MODE_MASK) > MSI_DATA_DELIVERY_LOWPRI)//temp + printk("MSI: addr=%08x%08x data=%08x dest=%08x (%08x) bogus!\n",//temp + entry->msg.address_hi, entry->msg.address_lo, entry->msg.data, entry->msg.dest32, msg->address_lo);//temp + } switch ( entry->msi_attrib.type ) { @@ -268,6 +280,11 @@ static void set_msi_affinity(struct irq_ memset(&msg, 0, sizeof(msg)); read_msi_msg(msi_desc, &msg); + if(!(msg.data & MSI_DATA_VECTOR_MASK) || !(msg.data & MSI_DATA_LEVEL_ASSERT)//temp + || (msg.data & MSI_DATA_DELIVERY_MODE_MASK) > MSI_DATA_DELIVERY_LOWPRI) {//temp + printk("MSI: addr=%08x%08x data=%08x bogus!\n", msg.address_hi, msg.address_lo, msg.data); + dump_execution_state(); + } msg.data &= ~MSI_DATA_VECTOR_MASK; msg.data |= MSI_DATA_VECTOR(desc->arch.vector); @@ -996,6 +1013,7 @@ int pci_restore_msi_state(struct pci_dev int ret; struct msi_desc *entry, *tmp; struct irq_desc *desc; + struct msi_msg msg; ASSERT(spin_is_locked(&pcidevs_lock)); @@ -1024,13 +1042,17 @@ int pci_restore_msi_state(struct pci_dev spin_unlock_irqrestore(&desc->lock, flags); return -EINVAL; } +printk("MSI[%04x:%02x:%02x:%u]: addr=%08x%08x data=%08x dest=%08x\n",//temp + pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),//temp + entry->msg.address_hi, entry->msg.address_lo, entry->msg.data, entry->msg.dest32);//temp if ( entry->msi_attrib.type == PCI_CAP_ID_MSI ) msi_set_enable(pdev, 0); else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX ) msix_set_enable(pdev, 0); - write_msi_msg(entry, &entry->msg); + msg = entry->msg; + write_msi_msg(entry, &msg); msi_set_mask_bit(desc, entry->msi_attrib.masked); --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1040,8 +1040,6 @@ static void dma_msi_mask(struct irq_desc unsigned long flags; struct iommu *iommu = desc->action->dev_id; - irq_complete_move(desc); - /* mask it */ spin_lock_irqsave(&iommu->register_lock, flags); dmar_writel(iommu->reg, DMAR_FECTL_REG, DMA_FECTL_IM); @@ -1054,6 +1052,13 @@ static unsigned int dma_msi_startup(stru return 0; } +static void dma_msi_ack(struct irq_desc *desc) +{ + irq_complete_move(desc); + dma_msi_mask(desc); + move_masked_irq(desc); +} + static void dma_msi_end(struct irq_desc *desc, u8 vector) { dma_msi_unmask(desc); @@ -1115,7 +1120,7 @@ static hw_irq_controller dma_msi_type = .shutdown = dma_msi_mask, .enable = dma_msi_unmask, .disable = dma_msi_mask, - .ack = dma_msi_mask, + .ack = dma_msi_ack, .end = dma_msi_end, .set_affinity = dma_msi_set_affinity, };