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] [linux-2.6.18-xen] Guest SR-IOV: Replace previous change

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Guest SR-IOV: Replace previous changeset with a more complete implementation from Intel
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 01 Mar 2010 02:00:08 -0800
Delivery-date: Mon, 01 Mar 2010 02:00:09 -0800
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 1267437309 0
# Node ID 4b0c1a686393ed4283e4942c6997354b7c37d370
# Parent  693c40564c8de65e32f48168bd8733918f661d7e
Guest SR-IOV: Replace previous changeset with a more complete implementation 
from Intel

"""Guest SR-IOV support for PV guest

These changes are for PV guest to use Virtual Function. Because the
VF's vendor, device registers in cfg space are 0xffff, which are
invalid and ignored by PCI device scan. Values in 'struct pci_dev' are
fixed up by SR-IOV code, and using these values will present correct
VID and DID to PV guest kernel.

And command registers in the cfg space are read only 0, which means we
have to emulate MMIO enable bit (VF only uses MMIO resource) so PV
kernel can work properly."""

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 drivers/xen/pciback/conf_space_header.c |  112 +++++++++++++++++++++++---------
 1 files changed, 81 insertions(+), 31 deletions(-)

diff -r 693c40564c8d -r 4b0c1a686393 drivers/xen/pciback/conf_space_header.c
--- a/drivers/xen/pciback/conf_space_header.c   Fri Feb 26 17:15:45 2010 +0000
+++ b/drivers/xen/pciback/conf_space_header.c   Mon Mar 01 09:55:09 2010 +0000
@@ -17,6 +17,25 @@ struct pci_bar_info {
 
 #define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
 #define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
+
+static int command_read(struct pci_dev *dev, int offset, u16 *value, void 
*data)
+{
+       int i;
+       int ret;
+
+       ret = pciback_read_config_word(dev, offset, value, data);
+       /*if (!atomic_read(&dev->enable_cnt))
+               return ret;*/
+
+       for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+               if (dev->resource[i].flags & IORESOURCE_IO)
+                       *value |= PCI_COMMAND_IO;
+               if (dev->resource[i].flags & IORESOURCE_MEM)
+                       *value |= PCI_COMMAND_MEMORY;
+       }
+
+       return ret;
+}
 
 static int command_write(struct pci_dev *dev, int offset, u16 value, void 
*data)
 {
@@ -73,7 +92,17 @@ static int rom_write(struct pci_dev *dev
        /* A write to obtain the length must happen as a 32-bit write.
         * This does not (yet) support writing individual bytes
         */
-       bar->which = (value == ~PCI_ROM_ADDRESS_ENABLE);
+       if (value == ~PCI_ROM_ADDRESS_ENABLE)
+               bar->which = 1;
+       else {
+               u32 tmpval;
+               pci_read_config_dword(dev, offset, &tmpval);
+               if (tmpval != bar->val && value == bar->val) {
+                       /* Allow restoration of bar value. */
+                       pci_write_config_dword(dev, offset, bar->val);
+               }
+               bar->which = 0;
+       }
 
        /* Do we need to support enabling/disabling the rom address here? */
 
@@ -97,7 +126,17 @@ static int bar_write(struct pci_dev *dev
        /* A write to obtain the length must happen as a 32-bit write.
         * This does not (yet) support writing individual bytes
         */
-       bar->which = (value == ~0);
+       if (value == ~0)
+               bar->which = 1;
+       else {
+               u32 tmpval;
+               pci_read_config_dword(dev, offset, &tmpval);
+               if (tmpval != bar->val && value == bar->val) {
+                       /* Allow restoration of bar value. */
+                       pci_write_config_dword(dev, offset, bar->val);
+               }
+               bar->which = 0;
+       }
 
        return 0;
 }
@@ -105,10 +144,6 @@ static int bar_read(struct pci_dev *dev,
 static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)
 {
        struct pci_bar_info *bar = data;
-       int idx = (offset - 0x10) >> 2;
-
-       if (idx > PCI_STD_RESOURCE_END )
-               idx = PCI_ROM_RESOURCE;
 
        if (unlikely(!bar)) {
                printk(KERN_WARNING "pciback: driver data not found for %s\n",
@@ -116,8 +151,7 @@ static int bar_read(struct pci_dev *dev,
                return XEN_PCI_ERR_op_failed;
        }
 
-       *value = bar->which ? ~(pci_resource_len(dev, idx)-1) : 
pci_resource_start(dev, idx);
-       *value |= pci_resource_flags(dev, idx) & 0xf;
+       *value = bar->which ? bar->len_val : bar->val;
 
        return 0;
 }
@@ -126,10 +160,26 @@ static inline void read_dev_bar(struct p
                                struct pci_bar_info *bar_info, int offset,
                                u32 len_mask)
 {
-       pci_read_config_dword(dev, offset, &bar_info->val);
-       pci_write_config_dword(dev, offset, len_mask);
-       pci_read_config_dword(dev, offset, &bar_info->len_val);
-       pci_write_config_dword(dev, offset, bar_info->val);
+       int     pos;
+       struct resource *res = dev->resource;
+
+       if (offset == PCI_ROM_ADDRESS || offset == PCI_ROM_ADDRESS1)
+               pos = PCI_ROM_RESOURCE;
+       else {
+               pos = (offset - PCI_BASE_ADDRESS_0) / 4;
+               if (pos && ((res[pos - 1].flags & (PCI_BASE_ADDRESS_SPACE |
+                               PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
+                          (PCI_BASE_ADDRESS_SPACE_MEMORY |
+                               PCI_BASE_ADDRESS_MEM_TYPE_64))) {
+                       bar_info->val = res[pos - 1].start >> 32;
+                       bar_info->len_val = res[pos - 1].end >> 32;
+                       return;
+               }
+       }
+
+       bar_info->val = res[pos].start |
+                       (res[pos].flags & PCI_REGION_FLAG_MASK);
+       bar_info->len_val = res[pos].end - res[pos].start + 1;
 }
 
 static void *bar_init(struct pci_dev *dev, int offset)
@@ -170,26 +220,26 @@ static void bar_release(struct pci_dev *
        kfree(data);
 }
 
+static int pciback_read_vendor(struct pci_dev *dev, int offset,
+                              u16 *value, void *data)
+{
+       *value = dev->vendor;
+
+       return 0;
+}
+
+static int pciback_read_device(struct pci_dev *dev, int offset,
+                              u16 *value, void *data)
+{
+       *value = dev->device;
+
+       return 0;
+}
+
 static int interrupt_read(struct pci_dev *dev, int offset, u8 * value,
                          void *data)
 {
        *value = (u8) dev->irq;
-
-       return 0;
-}
-
-static int vendor_read(struct pci_dev *dev, int offset, u16 * value,
-                      void *data)
-{
-       *value = dev->vendor;
-
-       return 0;
-}
-
-static int device_read(struct pci_dev *dev, int offset, u16 * value,
-                      void *data)
-{
-       *value = dev->device;
 
        return 0;
 }
@@ -215,17 +265,17 @@ static const struct config_field header_
        {
         .offset    = PCI_VENDOR_ID,
         .size      = 2,
-        .u.w.read  = vendor_read
+        .u.w.read  = pciback_read_vendor,
        },
        {
         .offset    = PCI_DEVICE_ID,
         .size      = 2,
-        .u.w.read  = device_read
+        .u.w.read  = pciback_read_device,
        },
        {
         .offset    = PCI_COMMAND,
         .size      = 2,
-        .u.w.read  = pciback_read_config_word,
+        .u.w.read  = command_read,
         .u.w.write = command_write,
        },
        {

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Guest SR-IOV: Replace previous changeset with a more complete implementation from Intel, Xen patchbot-linux-2.6.18-xen <=