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] Qemu: support SR-IOV Virtual Function passthrough

To: Ian.Jackson@xxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Qemu: support SR-IOV Virtual Function passthrough
From: Yu Zhao <yu.zhao@xxxxxxxxx>
Date: Wed, 18 Mar 2009 17:31:34 +0800
Cc: Yu Zhao <yu.zhao@xxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Wed, 18 Mar 2009 02:31:32 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Emulate the Memory Space Enable bit in the Command register because it's
hardwired to 0 for the Virtual Function.

Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx>
---
 hw/pass-through.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++---
 hw/pass-through.h |    5 +++--
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/hw/pass-through.c b/hw/pass-through.c
index ed69265..f334d63 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -102,6 +102,9 @@ static int pt_word_reg_read(struct pt_dev *ptdev,
 static int pt_long_reg_read(struct pt_dev *ptdev,
     struct pt_reg_tbl *cfg_entry,
     uint32_t *value, uint32_t valid_mask);
+static int pt_cmd_reg_read(struct pt_dev *ptdev,
+    struct pt_reg_tbl *cfg_entry,
+    uint16_t *value, uint16_t valid_mask);
 static int pt_bar_reg_read(struct pt_dev *ptdev,
     struct pt_reg_tbl *cfg_entry,
     uint32_t *value, uint32_t valid_mask);
@@ -207,7 +210,7 @@ static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = {
         .ro_mask    = 0xF880,
         .emu_mask   = 0x0340,
         .init       = pt_common_reg_init,
-        .u.w.read   = pt_word_reg_read,
+        .u.w.read   = pt_cmd_reg_read,
         .u.w.write  = pt_cmd_reg_write,
         .u.w.restore  = pt_cmd_reg_restore,
     },
@@ -1498,6 +1501,23 @@ static void pt_libpci_fixup(struct pci_dev *dev)
 #endif /* PCI_LIB_VERSION < 0x030100 */
 }
 
+static int pt_dev_is_virtfn(struct pci_dev *dev)
+{
+    int rc;
+    char path[PATH_MAX];
+    struct stat buf;
+
+    sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%x/physfn",
+            dev->domain, dev->bus, dev->dev, dev->func);
+
+    rc = !stat(path, &buf);
+    if ( rc )
+        PT_LOG("%04x:%02x:%02x.%x is a SR-IOV Virtual Function\n",
+               dev->domain, dev->bus, dev->dev, dev->func);
+
+    return rc;
+}
+
 static int pt_register_regions(struct pt_dev *assigned_device)
 {
     int i = 0;
@@ -2778,6 +2798,25 @@ static int pt_long_reg_read(struct pt_dev *ptdev,
    return 0;
 }
 
+/* read Command register */
+static int pt_cmd_reg_read(struct pt_dev *ptdev,
+        struct pt_reg_tbl *cfg_entry,
+        uint16_t *value, uint16_t valid_mask)
+{
+    struct pt_reg_info_tbl *reg = cfg_entry->reg;
+    uint16_t valid_emu_mask = 0;
+    uint16_t emu_mask = reg->emu_mask;
+
+    if ( ptdev->is_virtfn )
+        emu_mask |= PCI_COMMAND_MEMORY;
+
+    /* emulate word register */
+    valid_emu_mask = emu_mask & valid_mask;
+    *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);
+
+    return 0;
+}
+
 /* read BAR */
 static int pt_bar_reg_read(struct pt_dev *ptdev,
         struct pt_reg_tbl *cfg_entry,
@@ -2912,13 +2951,17 @@ static int pt_cmd_reg_write(struct pt_dev *ptdev,
     uint16_t writable_mask = 0;
     uint16_t throughable_mask = 0;
     uint16_t wr_value = *value;
+    uint16_t emu_mask = reg->emu_mask;
+
+    if ( ptdev->is_virtfn )
+        emu_mask |= PCI_COMMAND_MEMORY;
 
     /* modify emulate register */
-    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
+    writable_mask = emu_mask & ~reg->ro_mask & valid_mask;
     cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
 
     /* create value for writing to I/O device register */
-    throughable_mask = ~reg->emu_mask & valid_mask;
+    throughable_mask = ~emu_mask & valid_mask;
     *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
 
     /* mapping BAR */
@@ -3711,6 +3754,7 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
     assigned_device->pci_dev = pci_dev;
     assigned_device->msi_trans_cap = msi_translate;
     assigned_device->power_mgmt = power_mgmt;
+    assigned_device->is_virtfn = pt_dev_is_virtfn(pci_dev);
 
     /* Assign device */
     machine_bdf.reg = 0;
diff --git a/hw/pass-through.h b/hw/pass-through.h
index b7b5a79..a0fe587 100644
--- a/hw/pass-through.h
+++ b/hw/pass-through.h
@@ -216,9 +216,10 @@ struct pt_dev {
     int machine_irq;                            /* saved pirq */
     /* Physical MSI to guest INTx translation when possible */
     int msi_trans_cap;
-    int msi_trans_en;
-    int power_mgmt;
+    unsigned msi_trans_en:1;
+    unsigned power_mgmt:1;
     struct pt_pm_info *pm_state;                /* PM virtualization */
+    unsigned is_virtfn:1;
 };
 
 /* Used for formatting PCI BDF into cf8 format */
-- 
1.5.6.4


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

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