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] ioemu: Fix MSI/MSI-X capability structure virtualiza

To: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] ioemu: Fix MSI/MSI-X capability structure virtualization code
From: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>
Date: Fri, 13 Mar 2009 13:57:58 +0900
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Thu, 12 Mar 2009 21:58:45 -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
This patch fixes MSI/MSI-X capability structure virtualization code.

Currently, xen does not support multiple message (multiple vector).
So multiple message capable field should be emulated and fixed to 0
(single vector).

With the patch, my FC-HBA works when I assign it to guest domain where
windows 2008 runs.


In addition to this, initial values of emulated registers should be
the same with initial values defined in PCI spec. If initial values
are not defined, they should be 0. The emulated field mask and
read-only field mask are also fixed.

Thanks,
--
Yuji Shimada


Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 308bcc3..487b08d 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -73,8 +73,6 @@ static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev,
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint32_t pt_msgctrl_reg_init(struct pt_dev *ptdev,
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_msgaddr32_reg_init(struct pt_dev *ptdev,
-    struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint32_t pt_msgaddr64_reg_init(struct pt_dev *ptdev,
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev,
@@ -552,8 +550,8 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .offset     = PCI_MSI_FLAGS, // 2
         .size       = 2,
         .init_val   = 0x0000,
-        .ro_mask    = 0x018E,
-        .emu_mask   = 0xFFFF,
+        .ro_mask    = 0xFF8E,
+        .emu_mask   = 0x007F,
         .init       = pt_msgctrl_reg_init,
         .u.w.read   = pt_word_reg_read,
         .u.w.write  = pt_msgctrl_reg_write,
@@ -564,9 +562,9 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .offset     = PCI_MSI_ADDRESS_LO, // 4
         .size       = 4,
         .init_val   = 0x00000000,
-        .ro_mask    = 0x00000FF0,    /* bit 4~11 is reserved for MSI in x86 */
+        .ro_mask    = 0x00000003,
         .emu_mask   = 0xFFFFFFFF,
-        .init       = pt_msgaddr32_reg_init,
+        .init       = pt_common_reg_init,
         .u.dw.read  = pt_long_reg_read,
         .u.dw.write = pt_msgaddr32_reg_write,
         .u.dw.restore = NULL,
@@ -588,7 +586,7 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .offset     = PCI_MSI_DATA_32, // 8
         .size       = 2,
         .init_val   = 0x0000,
-        .ro_mask    = 0x3800,
+        .ro_mask    = 0x0000,
         .emu_mask   = 0xFFFF,
         .init       = pt_msgdata_reg_init,
         .u.w.read   = pt_word_reg_read,
@@ -600,7 +598,7 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .offset     = PCI_MSI_DATA_64, // 12
         .size       = 2,
         .init_val   = 0x0000,
-        .ro_mask    = 0x3800,
+        .ro_mask    = 0x0000,
         .emu_mask   = 0xFFFF,
         .init       = pt_msgdata_reg_init,
         .u.w.read   = pt_word_reg_read,
@@ -2456,7 +2454,7 @@ static uint32_t pt_msgctrl_reg_init(struct pt_dev *ptdev,
     uint32_t reg_field = 0;
 
     /* use I/O device register's value as initial value */
-    reg_field |= *((uint16_t*)(d->config + real_offset));
+    reg_field = *((uint16_t*)(d->config + real_offset));
 
     if (reg_field & PCI_MSI_FLAGS_ENABLE)
     {
@@ -2466,40 +2464,18 @@ static uint32_t pt_msgctrl_reg_init(struct pt_dev 
*ptdev,
     ptdev->msi->flags |= (reg_field | MSI_FLAG_UNINIT);
     ptdev->msi->ctrl_offset = real_offset;
 
-    /* All register is 0 after reset, except first 4 byte */
-    reg_field &= reg->ro_mask;
-
-    return reg_field;
-}
-
-/* initialize Message Address register */
-static uint32_t pt_msgaddr32_reg_init(struct pt_dev *ptdev,
-        struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
-    PCIDevice *d = (struct PCIDevice *)ptdev;
-    uint32_t reg_field = 0;
-
-    /* use I/O device register's value as initial value */
-    reg_field |= *((uint32_t*)(d->config + real_offset));
-
-    return reg_field;
+    return reg->init_val;
 }
 
 /* initialize Message Upper Address register */
 static uint32_t pt_msgaddr64_reg_init(struct pt_dev *ptdev,
         struct pt_reg_info_tbl *reg, uint32_t real_offset)
 {
-    PCIDevice *d = (struct PCIDevice *)ptdev;
-    uint32_t reg_field = 0;
-
     /* no need to initialize in case of 32 bit type */
     if (!(ptdev->msi->flags & PCI_MSI_FLAGS_64BIT))
         return PT_INVALID_REG;
 
-    /* use I/O device register's value as initial value */
-    reg_field |= *((uint32_t*)(d->config + real_offset));
-
-    return reg_field;
+    return reg->init_val;
 }
 
 /* this function will be called twice (for 32 bit and 64 bit type) */
@@ -2507,14 +2483,13 @@ static uint32_t pt_msgaddr64_reg_init(struct pt_dev 
*ptdev,
 static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev,
         struct pt_reg_info_tbl *reg, uint32_t real_offset)
 {
-    PCIDevice *d = (struct PCIDevice *)ptdev;
     uint32_t flags = ptdev->msi->flags;
     uint32_t offset = reg->offset;
 
     /* check the offset whether matches the type or not */
     if (((offset == PCI_MSI_DATA_64) &&  (flags & PCI_MSI_FLAGS_64BIT)) ||
         ((offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT)))
-        return *((uint16_t*)(d->config + real_offset));
+        return reg->init_val;
     else
         return PT_INVALID_REG;
 }
@@ -2528,18 +2503,17 @@ static uint32_t pt_msixctrl_reg_init(struct pt_dev 
*ptdev,
     uint16_t reg_field = 0;
 
     /* use I/O device register's value as initial value */
-    reg_field |= *((uint16_t*)(d->config + real_offset));
+    reg_field = *((uint16_t*)(d->config + real_offset));
 
     if (reg_field & PCI_MSIX_ENABLE)
     {
         PT_LOG("MSIX enabled already, disable first\n");
         pci_write_word(pdev, real_offset, reg_field & ~PCI_MSIX_ENABLE);
-        reg_field &= ~(PCI_MSIX_ENABLE | PCI_MSIX_MASK);
     }
 
     ptdev->msix->ctrl_offset = real_offset;
 
-    return reg_field;
+    return reg->init_val;
 }
 
 /* get register group size */


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

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