From 176a166180c208b26906a2c2decc3b8965483ae6 Mon Sep 17 00:00:00 2001
Message-Id: <176a166180c208b26906a2c2decc3b8965483ae6.1343746747.git.minovotn@redhat.com>
In-Reply-To: <a05f97bf1253f4585f1a6c3f03925d7d24a064f4.1343746747.git.minovotn@redhat.com>
References: <a05f97bf1253f4585f1a6c3f03925d7d24a064f4.1343746747.git.minovotn@redhat.com>
From: Alex Williamson <alex.williamson@redhat.com>
Date: Fri, 27 Jul 2012 19:47:28 +0200
Subject: [PATCH 5/6] pci-assign: Allocate entries for all MSI-X vectors

RH-Author: Alex Williamson <alex.williamson@redhat.com>
Message-id: <20120727194728.6928.11845.stgit@bling.home>
Patchwork-id: 40444
O-Subject: [RHEL6.4 qemu-kvm PATCH 4/5] pci-assign: Allocate entries for all MSI-X vectors
Bugzilla: 784496
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Don Dutile <ddutile@redhat.com>
RH-Acked-by: Jason Baron <jbaron@redhat.com>

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=784496
Upstream commit c6e3c4e76db9da7c74b27b48c9499f8f4c82f57a

We still only initialize the number used in the host.  This lets
us do direct access based on MSI-X table offset on write without
needing to translate between physical vector space and initalized
vector space.  It's expected that guests will typically use the
majority of the available vectors, so we're likely not allocating
significantly more entires than are used.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---

 hw/device-assignment.c |   44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/device-assignment.c |   44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 46bbdec..fba1dff 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -834,8 +834,11 @@ static void free_dev_irq_entries(AssignedDevice *dev)
 {
     int i;
 
-    for (i = 0; i < dev->irq_entries_nr; i++)
-        kvm_del_routing_entry(kvm_context, &dev->entry[i]);
+    for (i = 0; i < dev->irq_entries_nr; i++) {
+        if (dev->entry[i].type) {
+            kvm_del_routing_entry(kvm_context, &dev->entry[i]);
+        }
+    }
     free(dev->entry);
     dev->entry = NULL;
     dev->irq_entries_nr = 0;
@@ -1146,7 +1149,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
         if (entry->data == 0) {
             continue;
         }
-        entries_nr ++;
+        entries_nr++;
     }
 
     if (entries_nr == 0) {
@@ -1164,19 +1167,17 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
     }
 
     free_dev_irq_entries(adev);
-    adev->irq_entries_nr = entries_nr;
-    adev->entry = calloc(entries_nr, sizeof(struct kvm_irq_routing_entry));
+
+    adev->irq_entries_nr = adev->msix_max;
+    adev->entry = qemu_mallocz(adev->msix_max * sizeof(*(adev->entry)));
     if (!adev->entry) {
         perror("assigned_dev_update_msix_mmio: ");
         return -errno;
     }
 
     msix_entry.assigned_dev_id = msix_nr.assigned_dev_id;
-    entries_nr = 0;
     entry = adev->msix_table;
     for (i = 0; i < adev->msix_max; i++, entry++) {
-        if (entries_nr >= msix_nr.entry_nr)
-            break;
         if (entry->data == 0) {
             continue;
         }
@@ -1185,26 +1186,25 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
         if (r < 0)
             return r;
 
-        adev->entry[entries_nr].gsi = r;
-        adev->entry[entries_nr].type = KVM_IRQ_ROUTING_MSI;
-        adev->entry[entries_nr].flags = 0;
-        adev->entry[entries_nr].u.msi.address_lo = entry->addr_lo;
-        adev->entry[entries_nr].u.msi.address_hi = entry->addr_hi;
-        adev->entry[entries_nr].u.msi.data = entry->data;
-        DEBUG("MSI-X data 0x%x, MSI-X addr_lo 0x%x\n!",
-              entry->data, entry->addr_lo);
-	kvm_add_routing_entry(kvm_context, &adev->entry[entries_nr]);
-
-        msix_entry.gsi = adev->entry[entries_nr].gsi;
+        adev->entry[i].gsi = r;
+        adev->entry[i].type = KVM_IRQ_ROUTING_MSI;
+        adev->entry[i].flags = 0;
+        adev->entry[i].u.msi.address_lo = entry->addr_lo;
+        adev->entry[i].u.msi.address_hi = entry->addr_hi;
+        adev->entry[i].u.msi.data = entry->data;
+
+        DEBUG("MSI-X vector %d, gsi %d, addr %08x_%08x, data %08x\n", i,
+              r, entry->addr_hi, entry->addr_lo, entry->data);
+
+        kvm_add_routing_entry(kvm_context, &adev->entry[i]);
+
+        msix_entry.gsi = adev->entry[i].gsi;
         msix_entry.entry = i;
         r = kvm_assign_set_msix_entry(kvm_context, &msix_entry);
         if (r) {
             fprintf(stderr, "fail to set MSI-X entry! %s\n", strerror(-r));
             break;
         }
-        DEBUG("MSI-X entry gsi 0x%x, entry %d\n!",
-                msix_entry.gsi, msix_entry.entry);
-        entries_nr ++;
     }
 
     if (r == 0 && kvm_commit_irq_routes(kvm_context) < 0) {
-- 
1.7.10.4

