summary refs log tree commit diff stats
path: root/hw/msix.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2009-11-25 12:24:14 +0200
committerMichael S. Tsirkin <mst@redhat.com>2009-12-01 18:00:14 +0200
commit98304c846d8866dae6322ef400ce6595b23cfc41 (patch)
tree7526a2fb68d30d9f82143c35eab444770f835083 /hw/msix.c
parent1f944c661a821774e7b8cfbf5560a238795f2a60 (diff)
downloadfocaccia-qemu-98304c846d8866dae6322ef400ce6595b23cfc41.tar.gz
focaccia-qemu-98304c846d8866dae6322ef400ce6595b23cfc41.zip
msix: clear pending bit of an unused vector
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 <mst@redhat.com>
Diffstat (limited to 'hw/msix.c')
-rw-r--r--hw/msix.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/hw/msix.c b/hw/msix.c
index 785e097d80..4bc6147234 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -105,14 +105,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;
-}
-
 /* Handle MSI-X capability config write. */
 void msix_write_config(PCIDevice *dev, uint32_t addr,
                        uint32_t val, int len)
@@ -271,6 +263,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)
 {
@@ -387,8 +389,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)