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

[Xen-devel] [PATCH 8/9] qemu: enable HMV guest SR-IOV support



Add SR-IOV support for HVM guest.

Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx>

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 77ab759..da1a86b 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -47,6 +47,10 @@ struct dpci_infos {
 /* prototype */
 static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
+static uint32_t pt_vendor_reg_init(struct pt_dev *ptdev,
+    struct pt_reg_info_tbl *reg, uint32_t real_offset);
+static uint32_t pt_device_reg_init(struct pt_dev *ptdev,
+    struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint32_t pt_ptr_reg_init(struct pt_dev *ptdev,
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint32_t pt_status_reg_init(struct pt_dev *ptdev,
@@ -90,6 +94,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);
@@ -151,6 +158,28 @@ static int pt_msixctrl_reg_write(struct pt_dev *ptdev,

 /* Header Type0 reg static infomation table */
 static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = {
+    /* Vendor ID reg */
+    {
+        .offset     = PCI_VENDOR_ID,
+        .size       = 2,
+        .init_val   = 0x0000,
+        .ro_mask    = 0xFFFF,
+        .emu_mask   = 0xFFFF,
+        .init       = pt_vendor_reg_init,
+        .u.w.read   = pt_word_reg_read,
+        .u.w.write  = pt_word_reg_write,
+    },
+    /* Device ID reg */
+    {
+        .offset     = PCI_DEVICE_ID,
+        .size       = 2,
+        .init_val   = 0x0000,
+        .ro_mask    = 0xFFFF,
+        .emu_mask   = 0xFFFF,
+        .init       = pt_device_reg_init,
+        .u.w.read   = pt_word_reg_read,
+        .u.w.write  = pt_word_reg_write,
+    },
     /* Command reg */
     {
         .offset     = PCI_COMMAND,
@@ -159,7 +188,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,
     },
     /* Capabilities Pointer reg */
@@ -1753,6 +1782,14 @@ static void pt_config_delete(struct pt_dev *ptdev)
     }
 }

+/* check if the device is a Virtual Function */
+static int pt_is_vf(struct pt_dev *ptdev)
+{
+    uint32_t head = PT_BAR_ALLF;    /* Vendor and Device ID */
+
+    return !memcmp(&head, ptdev->dev.config, sizeof(head));
+}
+
 /* initialize common register value */
 static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
         struct pt_reg_info_tbl *reg, uint32_t real_offset)
@@ -1760,6 +1797,20 @@ static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
     return reg->init_val;
 }

+/* initialize Vendor ID register value */
+static uint32_t pt_vendor_reg_init(struct pt_dev *ptdev,
+        struct pt_reg_info_tbl *reg, uint32_t real_offset)
+{
+    return ptdev->pci_dev->vendor_id;
+}
+
+/* initialize Device ID register value */
+static uint32_t pt_device_reg_init(struct pt_dev *ptdev,
+        struct pt_reg_info_tbl *reg, uint32_t real_offset)
+{
+    return ptdev->pci_dev->device_id;
+}
+
 /* initialize Capabilities Pointer or Next Pointer register */
 static uint32_t pt_ptr_reg_init(struct pt_dev *ptdev,
         struct pt_reg_info_tbl *reg, uint32_t real_offset)
@@ -2218,6 +2269,26 @@ 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 (pt_is_vf(ptdev))
+        emu_mask |= PCI_COMMAND_MEMORY;
+
+    /* emulate word register */
+    valid_emu_mask = emu_mask & valid_mask;
+    *value = ((*value & ~valid_emu_mask) |
+              (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,
@@ -2337,14 +2408,18 @@ 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 (pt_is_vf(ptdev))
+        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 = ((*value & writable_mask) |
                        (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 = ((*value & throughable_mask) | (dev_value & ~throughable_mask));

     /* mapping BAR */

_______________________________________________
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®.