WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 2/2] ioemu: passthrough: MSI-X mask bit acceleration

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 2/2] ioemu: passthrough: MSI-X mask bit acceleration
From: Qing He <qing.he@xxxxxxxxx>
Date: Thu, 26 Feb 2009 17:28:06 +0800
Delivery-date: Thu, 26 Feb 2009 01:28:09 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1235640486-20584-1-git-send-email-qing.he@xxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1235640486-20584-1-git-send-email-qing.he@xxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Read MSI-X mask bit directly from the device, since buffered version
may not be up-to-date when MSI-X mask bit interception is working.
Also rebind every MSI-X vector on guest PCI BAR rebalancing so that
MSI-X mask bit intercept handler can get the correct gpa

Signed-off-by: Qing He <qing.he@xxxxxxxxx>
---
 pass-through.c |    3 +++
 pt-msi.c       |   41 ++++++++++++++++++++++++++++++++++++++---
 pt-msi.h       |    3 +++
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 96e7160..df6bd1e 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -983,6 +983,9 @@ void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, 
uint32_t e_size,
         ret = remove_msix_mapping(assigned_device, i);
         if ( ret != 0 )
             PT_LOG("Error: remove MSI-X mmio mapping failed!\n");
+
+        if ( old_ebase != e_phys && old_ebase != -1 )
+            pt_msix_update_remap(assigned_device, i);
     }
 }
 
diff --git a/hw/pt-msi.c b/hw/pt-msi.c
index ba86d7a..887f0a2 100644
--- a/hw/pt-msi.c
+++ b/hw/pt-msi.c
@@ -127,7 +127,7 @@ int pt_msi_update(struct pt_dev *d)
 
     PT_LOG("Update msi with pirq %x gvec %x\n", d->msi->pirq, gvec);
     return xc_domain_update_msi_irq(xc_handle, domid, gvec,
-                                     d->msi->pirq, gflags);
+                                     d->msi->pirq, gflags, 0);
 }
 
 void pt_msi_disable(struct pt_dev *dev)
@@ -304,7 +304,8 @@ static int pt_msix_update_one(struct pt_dev *dev, int 
entry_nr)
     PT_LOG("Update msix entry %x with pirq %x gvec %x\n",
             entry_nr, pirq, gvec);
 
-    ret = xc_domain_update_msi_irq(xc_handle, domid, gvec, pirq, gflags);
+    ret = xc_domain_update_msi_irq(xc_handle, domid, gvec, pirq, gflags,
+                                   dev->msix->mmio_base_addr);
     if ( ret )
     {
         PT_LOG("Error: Updating msix irq info for entry %d\n", entry_nr);
@@ -375,6 +376,31 @@ void pt_msix_disable(struct pt_dev *dev)
     }
 }
 
+int pt_msix_update_remap(struct pt_dev *dev, int bar_index)
+{
+    struct msix_entry_info *entry;
+    int i, ret;
+
+    if ( !(dev->msix && dev->msix->bar_index == bar_index) )
+        return 0;
+
+    for ( i = 0; i < dev->msix->total_entries; i++ )
+    {
+        entry = &dev->msix->msix_entry[i];
+        if ( entry->pirq != -1 )
+        {
+            ret = xc_domain_unbind_pt_irq(xc_handle, domid, entry->pirq,
+                                          PT_IRQ_TYPE_MSI, 0, 0, 0, 0);
+            if ( ret )
+                PT_LOG("Error: unbind MSI-X entry %d failed\n", entry->pirq);
+            entry->flags = 1;
+        }
+    }
+    pt_msix_update(dev);
+
+    return 0;
+}
+
 static void pci_msix_invalid_write(void *opaque, target_phys_addr_t addr,
                                    uint32_t val)
 {
@@ -388,6 +414,8 @@ static void pci_msix_writel(void *opaque, 
target_phys_addr_t addr, uint32_t val)
     struct pt_msix_info *msix = dev->msix;
     struct msix_entry_info *entry;
     int entry_nr, offset;
+    void *phys_off;
+    uint32_t vec_ctrl;
 
     if ( addr % 4 )
     {
@@ -400,7 +428,14 @@ static void pci_msix_writel(void *opaque, 
target_phys_addr_t addr, uint32_t val)
     entry = &msix->msix_entry[entry_nr];
     offset = ((addr - msix->mmio_base_addr) % 16) / 4;
 
-    if ( offset != 3 && msix->enabled && !(entry->io_mem[3] & 0x1) )
+    /*
+     * If Xen intercepts the mask bit access, io_mem[3] may not be
+     * up-to-date. Read from hardware directly.
+     */
+    phys_off = dev->msix->phys_iomem_base + 16 * entry_nr + 12;
+    vec_ctrl = *(uint32_t *)phys_off;
+
+    if ( offset != 3 && msix->enabled && !(vec_ctrl & 0x1) )
     {
         PT_LOG("Error: Can't update msix entry %d since MSI-X is already \
                 function.\n", entry_nr);
diff --git a/hw/pt-msi.h b/hw/pt-msi.h
index dea0848..d9c3f88 100644
--- a/hw/pt-msi.h
+++ b/hw/pt-msi.h
@@ -95,6 +95,9 @@ void
 pt_disable_msi_translate(struct pt_dev *dev);
 
 int
+pt_msi_update_remap(struct pt_dev *d, int bar_index);
+
+int
 pt_msix_update(struct pt_dev *dev);
 
 void

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>