PCI spec states: if a masked vector has its Pending bit set, and the associated underlying interrupt events are somehow satisfied (usually by software though the exact manner is function-specific), the function must clear the Pending bit, to avoid sending a spurious interrupt message later when software unmasks the vector.
In our case this happens if vector becomes unused. Clear pending bit in this case. Signed-off-by: Michael S. Tsirkin <m...@redhat.com> --- hw/msix.c | 27 +++++++++++++++++---------- 1 files changed, 17 insertions(+), 10 deletions(-) diff --git a/hw/msix.c b/hw/msix.c index a60ea95..0baedef 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -108,14 +108,6 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries, return 0; } -static void msix_free_irq_entries(PCIDevice *dev) -{ - int vector; - - for (vector = 0; vector < dev->msix_entries_nr; ++vector) - dev->msix_entry_used[vector] = 0; -} - static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr) { PCIDevice *dev = opaque; @@ -299,6 +291,16 @@ err_index: return ret; } +static void msix_free_irq_entries(PCIDevice *dev) +{ + int vector; + + for (vector = 0; vector < dev->msix_entries_nr; ++vector) { + dev->msix_entry_used[vector] = 0; + msix_clr_pending(dev, vector); + } +} + /* Clean up resources for the device. */ int msix_uninit(PCIDevice *dev) { @@ -415,8 +417,13 @@ int msix_vector_use(PCIDevice *dev, unsigned vector) /* Mark vector as unused. */ void msix_vector_unuse(PCIDevice *dev, unsigned vector) { - if (vector < dev->msix_entries_nr && dev->msix_entry_used[vector]) - --dev->msix_entry_used[vector]; + if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) { + return; + } + if (--dev->msix_entry_used[vector]) { + return; + } + msix_clr_pending(dev, vector); } void msix_unuse_all_vectors(PCIDevice *dev) -- 1.6.5.2.143.g8cc62