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

Re: [Xen-devel] [PATCH] ioemu: Fix MSI/MSI-X capability structure virtualization code



Could you consider applying the following patches?
They fix the bugs of PCI pass-through.

[PATCH] ioemu: Fix MSI/MSI-X capability structure virtualization code
[PATCH] ioemu: fix pt_chk_bar_overlap
[PATCH] ioemu: unmap INTx interrupt on hot-remove

Thanks,
--
Yuji Shimada

On Fri, 13 Mar 2009 13:57:58 +0900
Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx> wrote:

> 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


 


Rackspace

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