[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] Qemu: support SR-IOV Virtual Function passthrough



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.