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-changelog

[Xen-changelog] [xen-unstable] MSI-X: enhancement

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] MSI-X: enhancement
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 13 Aug 2008 08:10:17 -0700
Delivery-date: Wed, 13 Aug 2008 08:10:56 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1218631539 -3600
# Node ID 0638a5c2cc9f2053f6025edf3ddc5ff12300924d
# Parent  644a9d219973b9b21fd0590eec38370f4fb8caae
MSI-X: enhancement

Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx>
---
 tools/ioemu/hw/pass-through.h |    1 
 tools/ioemu/hw/pt-msi.c       |   24 +++++-------
 tools/libxc/xc_physdev.c      |   10 ++---
 tools/libxc/xenctrl.h         |    2 -
 xen/arch/x86/msi.c            |   82 +++++++++++++++---------------------------
 xen/arch/x86/physdev.c        |   15 +++++--
 xen/drivers/passthrough/io.c  |    3 +
 xen/include/asm-x86/msi.h     |   10 ++++-
 xen/include/public/physdev.h  |   11 +++--
 9 files changed, 76 insertions(+), 82 deletions(-)

diff -r 644a9d219973 -r 0638a5c2cc9f tools/ioemu/hw/pass-through.h
--- a/tools/ioemu/hw/pass-through.h     Wed Aug 13 13:42:30 2008 +0100
+++ b/tools/ioemu/hw/pass-through.h     Wed Aug 13 13:45:39 2008 +0100
@@ -120,6 +120,7 @@ struct pt_msix_info {
     int enabled;
     int total_entries;
     int bar_index;
+    uint64_t table_base;
     uint32_t table_off;
     uint64_t mmio_base_addr;
     int mmio_index;
diff -r 644a9d219973 -r 0638a5c2cc9f tools/ioemu/hw/pt-msi.c
--- a/tools/ioemu/hw/pt-msi.c   Wed Aug 13 13:42:30 2008 +0100
+++ b/tools/ioemu/hw/pt-msi.c   Wed Aug 13 13:45:39 2008 +0100
@@ -38,8 +38,8 @@ int pt_msi_setup(struct pt_dev *dev)
     }
 
     if ( xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq,
-                                                       dev->pci_dev->dev << 3 
| dev->pci_dev->func,
-                                                       dev->pci_dev->bus, 0, 
1) )
+                                 dev->pci_dev->dev << 3 | dev->pci_dev->func,
+                                 dev->pci_dev->bus, 0, 0) )
     {
         PT_LOG("error map msi\n");
         return -1;
@@ -121,7 +121,8 @@ static int pt_msix_update_one(struct pt_
     {
         ret = xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq,
                                 dev->pci_dev->dev << 3 | dev->pci_dev->func,
-                                dev->pci_dev->bus, entry_nr, 0);
+                                dev->pci_dev->bus, entry_nr,
+                                dev->msix->table_base);
         if ( ret )
         {
             PT_LOG("error map msix entry %x\n", entry_nr);
@@ -183,7 +184,7 @@ static void pci_msix_writel(void *opaque
     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 ( offset != 3 && msix->enabled && !(entry->io_mem[3] & 0x1) )
     {
         PT_LOG("can not update msix entry %d since MSI-X is already \
                 function now.\n", entry_nr);
@@ -196,7 +197,7 @@ static void pci_msix_writel(void *opaque
 
     if ( offset == 3 )
     {
-        if ( !(val & 0x1) )
+        if ( msix->enabled && !(val & 0x1) )
             pt_msix_update_one(dev, entry_nr);
         mask_physical_msix_entry(dev, entry_nr, entry->io_mem[3] & 0x1);
     }
@@ -280,7 +281,6 @@ int pt_msix_init(struct pt_dev *dev, int
     uint8_t id;
     uint16_t control;
     int i, total_entries, table_off, bar_index;
-    uint64_t bar_base;
     struct pci_dev *pd = dev->pci_dev;
 
     id = pci_read_byte(pd, pos + PCI_CAP_LIST_ID);
@@ -314,18 +314,14 @@ int pt_msix_init(struct pt_dev *dev, int
     table_off = pci_read_long(pd, pos + PCI_MSIX_TABLE);
     bar_index = dev->msix->bar_index = table_off & PCI_MSIX_BIR;
     table_off &= table_off & ~PCI_MSIX_BIR;
-    bar_base = pci_read_long(pd, 0x10 + 4 * bar_index);
-    if ( (bar_base & 0x6) == 0x4 )
-    {
-        bar_base &= ~0xf;
-        bar_base += (uint64_t)pci_read_long(pd, 0x10 + 4 * (bar_index + 1)) << 
32;
-    }
-    PT_LOG("get MSI-X table bar base %lx\n", bar_base);
+    dev->msix->table_base = dev->pci_dev->base_addr[bar_index];
+    PT_LOG("get MSI-X table bar base %llx\n",
+           (unsigned long long)dev->msix->table_base);
 
     dev->msix->fd = open("/dev/mem", O_RDWR);
     dev->msix->phys_iomem_base = mmap(0, total_entries * 16,
                           PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED,
-                          dev->msix->fd, bar_base + table_off);
+                          dev->msix->fd, dev->msix->table_base + table_off);
     PT_LOG("mapping physical MSI-X table to %lx\n",
            (unsigned long)dev->msix->phys_iomem_base);
     return 0;
diff -r 644a9d219973 -r 0638a5c2cc9f tools/libxc/xc_physdev.c
--- a/tools/libxc/xc_physdev.c  Wed Aug 13 13:42:30 2008 +0100
+++ b/tools/libxc/xc_physdev.c  Wed Aug 13 13:45:39 2008 +0100
@@ -51,7 +51,7 @@ int xc_physdev_map_pirq_msi(int xc_handl
                             int devfn,
                             int bus,
                             int entry_nr,
-                            int msi_type)
+                            uint64_t table_base)
 {
     int rc;
     struct physdev_map_pirq map;
@@ -63,10 +63,10 @@ int xc_physdev_map_pirq_msi(int xc_handl
     map.type = MAP_PIRQ_TYPE_MSI;
     map.index = index;
     map.pirq = *pirq;
-    map.msi_info.devfn = devfn;
-    map.msi_info.bus = bus;
-    map.msi_info.entry_nr = entry_nr;
-    map.msi_info.msi = msi_type;
+    map.bus = bus;
+    map.devfn = devfn;
+    map.entry_nr = entry_nr;
+    map.table_base = table_base;
 
     rc = do_physdev_op(xc_handle, PHYSDEVOP_map_pirq, &map);
 
diff -r 644a9d219973 -r 0638a5c2cc9f tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Aug 13 13:42:30 2008 +0100
+++ b/tools/libxc/xenctrl.h     Wed Aug 13 13:45:39 2008 +0100
@@ -917,7 +917,7 @@ int xc_physdev_map_pirq_msi(int xc_handl
                             int devfn,
                             int bus,
                             int entry_nr,
-                            int msi_type);
+                            uint64_t table_base);
 
 int xc_physdev_unmap_pirq(int xc_handle,
                           int domid,
diff -r 644a9d219973 -r 0638a5c2cc9f xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c        Wed Aug 13 13:42:30 2008 +0100
+++ b/xen/arch/x86/msi.c        Wed Aug 13 13:45:39 2008 +0100
@@ -490,28 +490,6 @@ static int msi_capability_init(struct pc
     return 0;
 }
 
-static u64 pci_resource_start(struct pci_dev *dev, u8 bar_index)
-{
-    u64 bar_base;
-    u32 reg_val;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
-
-    reg_val = pci_conf_read32(bus, slot, func,
-                              PCI_BASE_ADDRESS_0 + 4 * bar_index);
-    bar_base = reg_val & PCI_BASE_ADDRESS_MEM_MASK;
-    if ( ( reg_val & PCI_BASE_ADDRESS_MEM_TYPE_MASK ) ==
-         PCI_BASE_ADDRESS_MEM_TYPE_64 )
-    {
-        reg_val = pci_conf_read32(bus, slot, func,
-                                  PCI_BASE_ADDRESS_0 + 4 * (bar_index + 1));
-        bar_base |= ((u64)reg_val) << 32;
-    }
-
-    return bar_base;
-}
-
 /**
  * msix_capability_init - configure device's MSI-X capability
  * @dev: pointer to the pci_dev data structure of MSI-X device function
@@ -522,7 +500,7 @@ static u64 pci_resource_start(struct pci
  * single MSI-X irq. A return of zero indicates the successful setup of
  * requested MSI-X entries with allocated irqs or non-zero for otherwise.
  **/
-static int msix_capability_init(struct pci_dev *dev, int vector, int entry_nr)
+static int msix_capability_init(struct pci_dev *dev, struct msi_info *msi)
 {
     struct msi_desc *entry;
     int pos;
@@ -549,7 +527,7 @@ static int msix_capability_init(struct p
     table_offset = pci_conf_read32(bus, slot, func, 
msix_table_offset_reg(pos));
     bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
     table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
-    phys_addr = pci_resource_start(dev, bir) + table_offset;
+    phys_addr = msi->table_base + table_offset;
     idx = msix_fixmap_alloc();
     if ( idx < 0 )
     {
@@ -561,11 +539,11 @@ static int msix_capability_init(struct p
 
     entry->msi_attrib.type = PCI_CAP_ID_MSIX;
     entry->msi_attrib.is_64 = 1;
-    entry->msi_attrib.entry_nr = entry_nr;
+    entry->msi_attrib.entry_nr = msi->entry_nr;
     entry->msi_attrib.maskbit = 1;
     entry->msi_attrib.masked = 1;
     entry->msi_attrib.pos = pos;
-    entry->vector = vector;
+    entry->vector = msi->vector;
     entry->dev = dev;
     entry->mask_base = base;
 
@@ -589,24 +567,25 @@ static int msix_capability_init(struct p
  * indicates the successful setup of an entry zero with the new MSI
  * irq or non-zero for otherwise.
  **/
-static int __pci_enable_msi(u8 bus, u8 devfn, int vector)
+static int __pci_enable_msi(struct msi_info *msi)
 {
     int status;
     struct pci_dev *pdev;
 
-    pdev = pci_lock_pdev(bus, devfn);
+    pdev = pci_lock_pdev(msi->bus, msi->devfn);
     if ( !pdev )
        return -ENODEV;
 
-    if ( find_msi_entry(pdev, vector, PCI_CAP_ID_MSI) )
+    if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSI) )
     {
        spin_unlock(&pdev->lock);
-        dprintk(XENLOG_WARNING, "vector %d has already mapped to MSI on device 
\
-            %02x:%02x.%01x.\n", vector, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_WARNING, "vector %d has already mapped to MSI on "
+            "device %02x:%02x.%01x.\n", msi->vector, msi->bus,
+            PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
         return 0;
     }
 
-    status = msi_capability_init(pdev, vector);
+    status = msi_capability_init(pdev, msi->vector);
     spin_unlock(&pdev->lock);
     return status;
 }
@@ -659,37 +638,37 @@ static void __pci_disable_msi(int vector
  * of irqs available. Driver should use the returned value to re-send
  * its request.
  **/
-static int __pci_enable_msix(u8 bus, u8 devfn, int vector, int entry_nr)
+static int __pci_enable_msix(struct msi_info *msi)
 {
     int status, pos, nr_entries;
     struct pci_dev *pdev;
     u16 control;
-    u8 slot = PCI_SLOT(devfn);
-    u8 func = PCI_FUNC(devfn);
-
-    pdev = pci_lock_pdev(bus, devfn);
+    u8 slot = PCI_SLOT(msi->devfn);
+    u8 func = PCI_FUNC(msi->devfn);
+
+    pdev = pci_lock_pdev(msi->bus, msi->devfn);
     if ( !pdev )
        return -ENODEV;
 
-    pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSIX);
-    control = pci_conf_read16(bus, slot, func, msi_control_reg(pos));
+    pos = pci_find_cap_offset(msi->bus, slot, func, PCI_CAP_ID_MSIX);
+    control = pci_conf_read16(msi->bus, slot, func, msi_control_reg(pos));
     nr_entries = multi_msix_capable(control);
-    if (entry_nr > nr_entries)
+    if (msi->entry_nr > nr_entries)
     {
        spin_unlock(&pdev->lock);
         return -EINVAL;
     }
 
-    if ( find_msi_entry(pdev, vector, PCI_CAP_ID_MSIX) )
+    if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSIX) )
     {
        spin_unlock(&pdev->lock);
-        dprintk(XENLOG_WARNING, "vector %d has already mapped to MSIX on \
-                device %02x:%02x.%01x.\n", vector, bus,
-                PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_WARNING, "vector %d has already mapped to MSIX on "
+                "device %02x:%02x.%01x.\n", msi->vector, msi->bus,
+                PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
         return 0;
     }
 
-    status = msix_capability_init(pdev, vector, entry_nr);
+    status = msix_capability_init(pdev, msi);
     spin_unlock(&pdev->lock);
     return status;
 }
@@ -727,13 +706,12 @@ static void __pci_disable_msix(int vecto
     spin_unlock(&dev->lock);
 }
 
-int pci_enable_msi(u8 bus, u8 devfn, int vector, int entry_nr, int msi)
-{
-    ASSERT(spin_is_locked(&irq_desc[vector].lock));
-    if ( msi )
-        return __pci_enable_msi(bus, devfn, vector);
-    else
-        return __pci_enable_msix(bus, devfn, vector, entry_nr);
+int pci_enable_msi(struct msi_info *msi)
+{
+    ASSERT(spin_is_locked(&irq_desc[msi->vector].lock));
+
+    return  msi->table_base ? __pci_enable_msix(msi) :
+                              __pci_enable_msi(msi);
 }
 
 void pci_disable_msi(int vector)
diff -r 644a9d219973 -r 0638a5c2cc9f xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Wed Aug 13 13:42:30 2008 +0100
+++ b/xen/arch/x86/physdev.c    Wed Aug 13 13:45:39 2008 +0100
@@ -66,6 +66,7 @@ static int map_domain_pirq(struct domain
 {
     int ret = 0;
     int old_vector, old_pirq;
+    struct msi_info msi;
 
     if ( d == NULL )
         return -EINVAL;
@@ -115,10 +116,14 @@ static int map_domain_pirq(struct domain
                      vector);
         desc->handler = &pci_msi_type;
 
-        ret = pci_enable_msi(map->msi_info.bus,
-                                    map->msi_info.devfn, vector,
-                                                        map->msi_info.entry_nr,
-                                                        map->msi_info.msi);
+        msi.bus = map->bus;
+        msi.devfn = map->devfn;
+        msi.entry_nr = map->entry_nr;
+        msi.table_base = map->table_base;
+        msi.vector = vector;
+
+        ret = pci_enable_msi(&msi);
+
         spin_unlock_irqrestore(&desc->lock, flags);
         if ( ret )
             goto done;
@@ -139,7 +144,7 @@ static int unmap_domain_pirq(struct doma
     int ret = 0;
     int vector;
 
-    if ( d == NULL || pirq < 0 || pirq > NR_PIRQS )
+    if ( d == NULL || pirq < 0 || pirq >= NR_PIRQS )
         return -EINVAL;
 
     if ( !IS_PRIV(current->domain) )
diff -r 644a9d219973 -r 0638a5c2cc9f xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c      Wed Aug 13 13:42:30 2008 +0100
+++ b/xen/drivers/passthrough/io.c      Wed Aug 13 13:45:39 2008 +0100
@@ -74,6 +74,9 @@ int pt_irq_create_bind_vtd(
     if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI )
     {
         int pirq = pt_irq_bind->machine_irq;
+
+        if ( pirq < 0 || pirq >= NR_IRQS )
+            return -EINVAL;
 
         if ( !(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_VALID ) )
         {
diff -r 644a9d219973 -r 0638a5c2cc9f xen/include/asm-x86/msi.h
--- a/xen/include/asm-x86/msi.h Wed Aug 13 13:42:30 2008 +0100
+++ b/xen/include/asm-x86/msi.h Wed Aug 13 13:45:39 2008 +0100
@@ -53,6 +53,14 @@
 #else
 #define MAX_MSIX_PAGES              32
 #endif
+
+struct msi_info {
+    int bus;
+    int devfn;
+    int vector;
+    int entry_nr;
+    uint64_t table_base;
+};
 
 struct msi_msg {
        u32     address_lo;     /* low 32 bits of msi message address */
@@ -64,7 +72,7 @@ extern void mask_msi_irq(unsigned int ir
 extern void mask_msi_irq(unsigned int irq);
 extern void unmask_msi_irq(unsigned int irq);
 extern void set_msi_irq_affinity(unsigned int irq, cpumask_t mask);
-extern int pci_enable_msi(u8 bus, u8 devfn, int vector, int entry_nr, int msi);
+extern int pci_enable_msi(struct msi_info *msi);
 extern void pci_disable_msi(int vector);
 extern void pci_cleanup_msi(struct pci_dev *pdev);
 
diff -r 644a9d219973 -r 0638a5c2cc9f xen/include/public/physdev.h
--- a/xen/include/public/physdev.h      Wed Aug 13 13:42:30 2008 +0100
+++ b/xen/include/public/physdev.h      Wed Aug 13 13:45:39 2008 +0100
@@ -136,10 +136,13 @@ struct physdev_map_pirq {
     /* IN or OUT */
     int pirq;
     /* IN */
-    struct {
-        int bus, devfn, entry_nr;
-               int msi;  /* 0 - MSIX    1 - MSI */
-    } msi_info;
+    int bus;
+    /* IN */
+    int devfn;
+    /* IN */
+    int entry_nr;
+    /* IN */
+    uint64_t table_base;
 };
 typedef struct physdev_map_pirq physdev_map_pirq_t;
 DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] MSI-X: enhancement, Xen patchbot-unstable <=