All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0
@ 2011-11-21 16:56 Michael S. Tsirkin
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state Michael S. Tsirkin
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-11-21 16:56 UTC (permalink / raw)
  To: qemu-devel
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, Alexander Graf,
	Michael S. Tsirkin

This fixes bugs dealing with msi-x mask bits pointed out by Jan Kiszka.

Jan Kiszka (1):
  msix: Prevent bogus mask updates on MMIO accesses

Michael S. Tsirkin (2):
  msix: track function masked in pci device state
  msix: avoid mask updates if mask is unchanged

 hw/msix.c |   48 ++++++++++++++++++++++++++++++++++++------------
 hw/pci.h  |    2 ++
 2 files changed, 38 insertions(+), 12 deletions(-)

-- 
1.7.5.53.gc233e

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-11-21 16:56 [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Michael S. Tsirkin
@ 2011-11-21 16:57 ` Michael S. Tsirkin
  2011-12-02 23:34   ` Cam Macdonell
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 2/3] msix: Prevent bogus mask updates on MMIO accesses Michael S. Tsirkin
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-11-21 16:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, Alexander Graf,
	Michael S. Tsirkin

Only go over the table when function is masked.
This is not really important for qemu.git but helps
fix a bug in qemu-kvm.git.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/msix.c |   21 ++++++++++++++-------
 hw/pci.h  |    2 ++
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index b15bafc..63b41b9 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -79,6 +79,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
     /* Make flags bit writable. */
     pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
 	    MSIX_MASKALL_MASK;
+    pdev->msix_function_masked = true;
     return 0;
 }
 
@@ -117,16 +118,11 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
     *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
 }
 
-static int msix_function_masked(PCIDevice *dev)
-{
-    return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK;
-}
-
 static int msix_is_masked(PCIDevice *dev, int vector)
 {
     unsigned offset =
         vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
-    return msix_function_masked(dev) ||
+    return dev->msix_function_masked ||
 	   dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
 }
 
@@ -138,24 +134,34 @@ static void msix_handle_mask_update(PCIDevice *dev, int vector)
     }
 }
 
+static void msix_update_function_masked(PCIDevice *dev)
+{
+    dev->msix_function_masked = !msix_enabled(dev) ||
+        (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK);
+}
+
 /* Handle MSI-X capability config write. */
 void msix_write_config(PCIDevice *dev, uint32_t addr,
                        uint32_t val, int len)
 {
     unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
     int vector;
+    bool was_masked;
 
     if (!range_covers_byte(addr, len, enable_pos)) {
         return;
     }
 
+    was_masked = dev->msix_function_masked;
+    msix_update_function_masked(dev);
+
     if (!msix_enabled(dev)) {
         return;
     }
 
     pci_device_deassert_intx(dev);
 
-    if (msix_function_masked(dev)) {
+    if (dev->msix_function_masked == was_masked) {
         return;
     }
 
@@ -300,6 +306,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
     msix_free_irq_entries(dev);
     qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
+    msix_update_function_masked(dev);
 }
 
 /* Does device support MSI-X? */
diff --git a/hw/pci.h b/hw/pci.h
index 4b2e785..625e717 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -178,6 +178,8 @@ struct PCIDevice {
     unsigned *msix_entry_used;
     /* Region including the MSI-X table */
     uint32_t msix_bar_size;
+    /* MSIX function mask set or MSIX disabled */
+    bool msix_function_masked;
     /* Version id needed for VMState */
     int32_t version_id;
 
-- 
1.7.5.53.gc233e

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH for v1.0 2/3] msix: Prevent bogus mask updates on MMIO accesses
  2011-11-21 16:56 [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Michael S. Tsirkin
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state Michael S. Tsirkin
@ 2011-11-21 16:57 ` Michael S. Tsirkin
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 3/3] msix: avoid mask updates if mask is unchanged Michael S. Tsirkin
  2011-11-22  0:23 ` [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Anthony Liguori
  3 siblings, 0 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-11-21 16:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, Alexander Graf,
	Michael S. Tsirkin

>From: Jan Kiszka <jan.kiszka@siemens.com>

Only accesses to the MSI-X table must trigger a call to
msix_handle_mask_update, otherwise the vector
value might be out of range.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/msix.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index 63b41b9..2969601 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -176,6 +176,12 @@ static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
     int vector = offset / PCI_MSIX_ENTRY_SIZE;
+
+    /* MSI-X page includes a read-only PBA and a writeable Vector Control. */
+    if (vector >= dev->msix_entries_nr) {
+        return;
+    }
+
     pci_set_long(dev->msix_table_page + offset, val);
     msix_handle_mask_update(dev, vector);
 }
-- 
1.7.5.53.gc233e

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH for v1.0 3/3] msix: avoid mask updates if mask is unchanged
  2011-11-21 16:56 [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Michael S. Tsirkin
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state Michael S. Tsirkin
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 2/3] msix: Prevent bogus mask updates on MMIO accesses Michael S. Tsirkin
@ 2011-11-21 16:57 ` Michael S. Tsirkin
  2011-11-22  0:23 ` [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Anthony Liguori
  3 siblings, 0 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-11-21 16:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, Alexander Graf,
	Michael S. Tsirkin

Check pending bit only if vector mask status changed.
This is not really important for qemu.git but helps
fix a bug in qemu-kvm.git.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/msix.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index 2969601..149eed2 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -118,17 +118,25 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
     *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
 }
 
-static int msix_is_masked(PCIDevice *dev, int vector)
+static bool msix_vector_masked(PCIDevice *dev, int vector, bool fmask)
 {
-    unsigned offset =
-        vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
-    return dev->msix_function_masked ||
-	   dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
+    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
+    return fmask || dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
 }
 
-static void msix_handle_mask_update(PCIDevice *dev, int vector)
+static bool msix_is_masked(PCIDevice *dev, int vector)
 {
-    if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) {
+    return msix_vector_masked(dev, vector, dev->msix_function_masked);
+}
+
+static void msix_handle_mask_update(PCIDevice *dev, int vector, bool was_masked)
+{
+    bool is_masked = msix_is_masked(dev, vector);
+    if (is_masked == was_masked) {
+        return;
+    }
+
+    if (!is_masked && msix_is_pending(dev, vector)) {
         msix_clr_pending(dev, vector);
         msix_notify(dev, vector);
     }
@@ -166,7 +174,8 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
     }
 
     for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
-        msix_handle_mask_update(dev, vector);
+        msix_handle_mask_update(dev, vector,
+                                msix_vector_masked(dev, vector, was_masked));
     }
 }
 
@@ -176,14 +185,16 @@ static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
     int vector = offset / PCI_MSIX_ENTRY_SIZE;
+    bool was_masked;
 
     /* MSI-X page includes a read-only PBA and a writeable Vector Control. */
     if (vector >= dev->msix_entries_nr) {
         return;
     }
 
+    was_masked = msix_is_masked(dev, vector);
     pci_set_long(dev->msix_table_page + offset, val);
-    msix_handle_mask_update(dev, vector);
+    msix_handle_mask_update(dev, vector, was_masked);
 }
 
 static const MemoryRegionOps msix_mmio_ops = {
-- 
1.7.5.53.gc233e

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0
  2011-11-21 16:56 [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Michael S. Tsirkin
                   ` (2 preceding siblings ...)
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 3/3] msix: avoid mask updates if mask is unchanged Michael S. Tsirkin
@ 2011-11-22  0:23 ` Anthony Liguori
  3 siblings, 0 replies; 17+ messages in thread
From: Anthony Liguori @ 2011-11-22  0:23 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Blue Swirl, Jan Kiszka, qemu-devel, Alexander Graf

On 11/21/2011 10:56 AM, Michael S. Tsirkin wrote:
> This fixes bugs dealing with msi-x mask bits pointed out by Jan Kiszka.

Applied.  Thanks.

Regards,

Anthony Liguori

>
> Jan Kiszka (1):
>    msix: Prevent bogus mask updates on MMIO accesses
>
> Michael S. Tsirkin (2):
>    msix: track function masked in pci device state
>    msix: avoid mask updates if mask is unchanged
>
>   hw/msix.c |   48 ++++++++++++++++++++++++++++++++++++------------
>   hw/pci.h  |    2 ++
>   2 files changed, 38 insertions(+), 12 deletions(-)
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state Michael S. Tsirkin
@ 2011-12-02 23:34   ` Cam Macdonell
  2011-12-03 10:46     ` Jan Kiszka
                       ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Cam Macdonell @ 2011-12-02 23:34 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

Based on a git bisect, this patch breaks msi-x interrupt delivery in
the ivshmem device.

On Mon, Nov 21, 2011 at 9:57 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> Only go over the table when function is masked.
> This is not really important for qemu.git but helps
> fix a bug in qemu-kvm.git.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>  hw/msix.c |   21 ++++++++++++++-------
>  hw/pci.h  |    2 ++
>  2 files changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/hw/msix.c b/hw/msix.c
> index b15bafc..63b41b9 100644
> --- a/hw/msix.c
> +++ b/hw/msix.c
> @@ -79,6 +79,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
>     /* Make flags bit writable. */
>     pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
>            MSIX_MASKALL_MASK;
> +    pdev->msix_function_masked = true;
>     return 0;

iiuc, this masks the msix by default.

>  }
>
> @@ -117,16 +118,11 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
>     *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
>  }
>
> -static int msix_function_masked(PCIDevice *dev)
> -{
> -    return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK;
> -}
> -
>  static int msix_is_masked(PCIDevice *dev, int vector)
>  {
>     unsigned offset =
>         vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
> -    return msix_function_masked(dev) ||
> +    return dev->msix_function_masked ||
>           dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
>  }
>
> @@ -138,24 +134,34 @@ static void msix_handle_mask_update(PCIDevice *dev, int vector)
>     }
>  }
>
> +static void msix_update_function_masked(PCIDevice *dev)
> +{
> +    dev->msix_function_masked = !msix_enabled(dev) ||
> +        (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK);
> +}
> +
>  /* Handle MSI-X capability config write. */
>  void msix_write_config(PCIDevice *dev, uint32_t addr,
>                        uint32_t val, int len)
>  {
>     unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
>     int vector;
> +    bool was_masked;
>
>     if (!range_covers_byte(addr, len, enable_pos)) {
>         return;
>     }
>
> +    was_masked = dev->msix_function_masked;
> +    msix_update_function_masked(dev);
> +
>     if (!msix_enabled(dev)) {
>         return;
>     }
>
>     pci_device_deassert_intx(dev);
>
> -    if (msix_function_masked(dev)) {
> +    if (dev->msix_function_masked == was_masked) {
>         return;
>     }

So I believe my bug is due to the fact the new logic included in this
patch requires msix_write_config() to be called to unmask the vectors.
 Virtio-pci calls msix_write_config(), but ivshmem does not (nor does
PCIe so I'm not sure if it's also affected).

I haven't been able to fix the bug yet, but I wanted to make sure I
was looking in the correct place.  Any help of further explanation of
this patch would be greatly appreciated.

Sincerely,
Cam

>
> @@ -300,6 +306,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
>     msix_free_irq_entries(dev);
>     qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
>     qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
> +    msix_update_function_masked(dev);
>  }
>
>  /* Does device support MSI-X? */
> diff --git a/hw/pci.h b/hw/pci.h
> index 4b2e785..625e717 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -178,6 +178,8 @@ struct PCIDevice {
>     unsigned *msix_entry_used;
>     /* Region including the MSI-X table */
>     uint32_t msix_bar_size;
> +    /* MSIX function mask set or MSIX disabled */
> +    bool msix_function_masked;
>     /* Version id needed for VMState */
>     int32_t version_id;
>
> --
> 1.7.5.53.gc233e
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-02 23:34   ` Cam Macdonell
@ 2011-12-03 10:46     ` Jan Kiszka
  2011-12-04 10:08     ` Michael S. Tsirkin
  2011-12-04 10:20     ` Michael S. Tsirkin
  2 siblings, 0 replies; 17+ messages in thread
From: Jan Kiszka @ 2011-12-03 10:46 UTC (permalink / raw)
  To: Cam Macdonell
  Cc: Blue Swirl, Alexander Graf, Anthony Liguori, qemu-devel,
	Michael S. Tsirkin

[-- Attachment #1: Type: text/plain, Size: 488 bytes --]

On 2011-12-03 00:34, Cam Macdonell wrote:
> So I believe my bug is due to the fact the new logic included in this
> patch requires msix_write_config() to be called to unmask the vectors.
>  Virtio-pci calls msix_write_config(), but ivshmem does not (nor does
> PCIe so I'm not sure if it's also affected).

msi[x]_write_config should not have to be called from device models but
it must be right now. I proposed a patch a while ago to improve this.
Same for msix_reset.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-02 23:34   ` Cam Macdonell
  2011-12-03 10:46     ` Jan Kiszka
@ 2011-12-04 10:08     ` Michael S. Tsirkin
  2011-12-04 10:20     ` Michael S. Tsirkin
  2 siblings, 0 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-12-04 10:08 UTC (permalink / raw)
  To: Cam Macdonell
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
> Based on a git bisect, this patch breaks msi-x interrupt delivery in
> the ivshmem device.
> 
> On Mon, Nov 21, 2011 at 9:57 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > Only go over the table when function is masked.
> > This is not really important for qemu.git but helps
> > fix a bug in qemu-kvm.git.
> >
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > ---
> >  hw/msix.c |   21 ++++++++++++++-------
> >  hw/pci.h  |    2 ++
> >  2 files changed, 16 insertions(+), 7 deletions(-)
> >
> > diff --git a/hw/msix.c b/hw/msix.c
> > index b15bafc..63b41b9 100644
> > --- a/hw/msix.c
> > +++ b/hw/msix.c
> > @@ -79,6 +79,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
> >     /* Make flags bit writable. */
> >     pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
> >            MSIX_MASKALL_MASK;
> > +    pdev->msix_function_masked = true;
> >     return 0;
> 
> iiuc, this masks the msix by default.

Yes, because msi-x is disabled by default, that's
in the pci spec.

> >  }
> >
> > @@ -117,16 +118,11 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
> >     *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
> >  }
> >
> > -static int msix_function_masked(PCIDevice *dev)
> > -{
> > -    return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK;
> > -}
> > -
> >  static int msix_is_masked(PCIDevice *dev, int vector)
> >  {
> >     unsigned offset =
> >         vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
> > -    return msix_function_masked(dev) ||
> > +    return dev->msix_function_masked ||
> >           dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
> >  }
> >
> > @@ -138,24 +134,34 @@ static void msix_handle_mask_update(PCIDevice *dev, int vector)
> >     }
> >  }
> >
> > +static void msix_update_function_masked(PCIDevice *dev)
> > +{
> > +    dev->msix_function_masked = !msix_enabled(dev) ||
> > +        (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK);
> > +}
> > +
> >  /* Handle MSI-X capability config write. */
> >  void msix_write_config(PCIDevice *dev, uint32_t addr,
> >                        uint32_t val, int len)
> >  {
> >     unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
> >     int vector;
> > +    bool was_masked;
> >
> >     if (!range_covers_byte(addr, len, enable_pos)) {
> >         return;
> >     }
> >
> > +    was_masked = dev->msix_function_masked;
> > +    msix_update_function_masked(dev);
> > +
> >     if (!msix_enabled(dev)) {
> >         return;
> >     }
> >
> >     pci_device_deassert_intx(dev);
> >
> > -    if (msix_function_masked(dev)) {
> > +    if (dev->msix_function_masked == was_masked) {
> >         return;
> >     }
> 
> So I believe my bug is due to the fact the new logic included in this
> patch requires msix_write_config() to be called to unmask the vectors.

Not exactly, to enable msi-x really.

>  Virtio-pci calls msix_write_config(), but ivshmem does not (nor does
> PCIe so I'm not sure if it's also affected).

At this point PCIe is a stub.

> I haven't been able to fix the bug yet, but I wanted to make sure I
> was looking in the correct place.  Any help of further explanation of
> this patch would be greatly appreciated.
> 
> Sincerely,
> Cam

So I think you just need to call msix_write_config,
otherwise msix is not getting enabled.

BTW looking at the ivshmem code, this bit looks wrong:

    pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY;

I think the spec says IO/MEMORY must be disabled at init time since BARs
are not yet set to anything reasonable.

> >
> > @@ -300,6 +306,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
> >     msix_free_irq_entries(dev);
> >     qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
> >     qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
> > +    msix_update_function_masked(dev);
> >  }
> >
> >  /* Does device support MSI-X? */
> > diff --git a/hw/pci.h b/hw/pci.h
> > index 4b2e785..625e717 100644
> > --- a/hw/pci.h
> > +++ b/hw/pci.h
> > @@ -178,6 +178,8 @@ struct PCIDevice {
> >     unsigned *msix_entry_used;
> >     /* Region including the MSI-X table */
> >     uint32_t msix_bar_size;
> > +    /* MSIX function mask set or MSIX disabled */
> > +    bool msix_function_masked;
> >     /* Version id needed for VMState */
> >     int32_t version_id;
> >
> > --
> > 1.7.5.53.gc233e
> >
> >

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-02 23:34   ` Cam Macdonell
  2011-12-03 10:46     ` Jan Kiszka
  2011-12-04 10:08     ` Michael S. Tsirkin
@ 2011-12-04 10:20     ` Michael S. Tsirkin
  2011-12-04 12:35       ` Jan Kiszka
  2011-12-04 23:47       ` Cam Macdonell
  2 siblings, 2 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-12-04 10:20 UTC (permalink / raw)
  To: Cam Macdonell
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
> Based on a git bisect, this patch breaks msi-x interrupt delivery in
> the ivshmem device.

I think the following should fix it. Compiled-only -
could you pls check? If yes let's apply to the stable branch.

-->

ivshmem: add missing msix calls

ivshmem used msix but didn't call it on either reset or
config write paths. This used to partically work since
guests don't use all of msi-x configuration fields,
and reset is rarely used, but the patch 'msix: track function masked
in pci device state' broke that. Fix by adding appropriate calls.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

--

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 242fbea..3680c0f 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -505,6 +505,7 @@ static void ivshmem_reset(DeviceState *d)
     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
 
     s->intrstatus = 0;
+    msix_reset(&s->dev);
     return;
 }
 
@@ -610,6 +611,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
     return 0;
 }
 
+static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
+				 uint32_t val, int len)
+{
+    pci_default_write_config(pci_dev, address, val, len);
+    msix_write_config(pci_dev, address, val, len);
+}
+
 static int pci_ivshmem_init(PCIDevice *dev)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
@@ -734,6 +742,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     }
 
+    s->dev.config_write = ivshmem_write_config;
+
     return 0;
 }
 

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-04 10:20     ` Michael S. Tsirkin
@ 2011-12-04 12:35       ` Jan Kiszka
  2011-12-04 13:03         ` Michael S. Tsirkin
  2011-12-04 23:47       ` Cam Macdonell
  1 sibling, 1 reply; 17+ messages in thread
From: Jan Kiszka @ 2011-12-04 12:35 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Blue Swirl, Anthony Liguori, Cam Macdonell, qemu-devel,
	Alexander Graf

[-- Attachment #1: Type: text/plain, Size: 2054 bytes --]

On 2011-12-04 11:20, Michael S. Tsirkin wrote:
> On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
>> Based on a git bisect, this patch breaks msi-x interrupt delivery in
>> the ivshmem device.
> 
> I think the following should fix it. Compiled-only -
> could you pls check? If yes let's apply to the stable branch.
> 
> -->
> 
> ivshmem: add missing msix calls
> 
> ivshmem used msix but didn't call it on either reset or
> config write paths. This used to partically work since
> guests don't use all of msi-x configuration fields,
> and reset is rarely used, but the patch 'msix: track function masked
> in pci device state' broke that. Fix by adding appropriate calls.
> 
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> 
> --
> 
> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
> index 242fbea..3680c0f 100644
> --- a/hw/ivshmem.c
> +++ b/hw/ivshmem.c
> @@ -505,6 +505,7 @@ static void ivshmem_reset(DeviceState *d)
>      IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
>  
>      s->intrstatus = 0;
> +    msix_reset(&s->dev);
>      return;
>  }
>  
> @@ -610,6 +611,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
>      return 0;
>  }
>  
> +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
> +				 uint32_t val, int len)
> +{
> +    pci_default_write_config(pci_dev, address, val, len);
> +    msix_write_config(pci_dev, address, val, len);
> +}
> +
>  static int pci_ivshmem_init(PCIDevice *dev)
>  {
>      IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> @@ -734,6 +742,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
>  
>      }
>  
> +    s->dev.config_write = ivshmem_write_config;
> +
>      return 0;
>  }
>  
> 
> 

But please fix this for real and merge [1]&[2] (with depending patches)
into master. The above is just boilerplate code from device POV.

Jan

[1] http://thread.gmane.org/gmane.comp.emulators.kvm.devel/80240
[2] http://thread.gmane.org/gmane.comp.emulators.kvm.devel/80244


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-04 12:35       ` Jan Kiszka
@ 2011-12-04 13:03         ` Michael S. Tsirkin
  0 siblings, 0 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-12-04 13:03 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Blue Swirl, Anthony Liguori, Cam Macdonell, qemu-devel,
	Alexander Graf

On Sun, Dec 04, 2011 at 01:35:03PM +0100, Jan Kiszka wrote:
> On 2011-12-04 11:20, Michael S. Tsirkin wrote:
> > On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
> >> Based on a git bisect, this patch breaks msi-x interrupt delivery in
> >> the ivshmem device.
> > 
> > I think the following should fix it. Compiled-only -
> > could you pls check? If yes let's apply to the stable branch.
> > 
> > -->
> > 
> > ivshmem: add missing msix calls
> > 
> > ivshmem used msix but didn't call it on either reset or
> > config write paths. This used to partically work since
> > guests don't use all of msi-x configuration fields,
> > and reset is rarely used, but the patch 'msix: track function masked
> > in pci device state' broke that. Fix by adding appropriate calls.
> > 
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > 
> > --
> > 
> > diff --git a/hw/ivshmem.c b/hw/ivshmem.c
> > index 242fbea..3680c0f 100644
> > --- a/hw/ivshmem.c
> > +++ b/hw/ivshmem.c
> > @@ -505,6 +505,7 @@ static void ivshmem_reset(DeviceState *d)
> >      IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
> >  
> >      s->intrstatus = 0;
> > +    msix_reset(&s->dev);
> >      return;
> >  }
> >  
> > @@ -610,6 +611,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
> >      return 0;
> >  }
> >  
> > +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
> > +				 uint32_t val, int len)
> > +{
> > +    pci_default_write_config(pci_dev, address, val, len);
> > +    msix_write_config(pci_dev, address, val, len);
> > +}
> > +
> >  static int pci_ivshmem_init(PCIDevice *dev)
> >  {
> >      IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> > @@ -734,6 +742,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
> >  
> >      }
> >  
> > +    s->dev.config_write = ivshmem_write_config;
> > +
> >      return 0;
> >  }
> >  
> > 
> > 
> 
> But please fix this for real and merge [1]&[2] (with depending patches)
> into master. The above is just boilerplate code from device POV.
> 
> Jan
> 
> [1] http://thread.gmane.org/gmane.comp.emulators.kvm.devel/80240
> [2] http://thread.gmane.org/gmane.comp.emulators.kvm.devel/80244
> 

Yes, I agree we should make it easier for devices.
What annoyed me was the need to put msix in save/load.

And that is because of the need to do this in a specific
order.  I hope to switch to an unordered format and
then this will become straight-forward.

-- 
MST

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-04 10:20     ` Michael S. Tsirkin
  2011-12-04 12:35       ` Jan Kiszka
@ 2011-12-04 23:47       ` Cam Macdonell
  2011-12-05  9:08         ` Michael S. Tsirkin
  2011-12-05 19:48         ` [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls Michael S. Tsirkin
  1 sibling, 2 replies; 17+ messages in thread
From: Cam Macdonell @ 2011-12-04 23:47 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

On Sun, Dec 4, 2011 at 3:20 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
>> Based on a git bisect, this patch breaks msi-x interrupt delivery in
>> the ivshmem device.
>
> I think the following should fix it. Compiled-only -
> could you pls check? If yes let's apply to the stable branch.

Thanks for the patch Michael.

It addresses the need for msix_write_config() to be called, but the
addition of the msix_reset() is causing a reset of the vectors after
they've been initialized in pci_ivshmem_init().  So, interrupts still
aren't delivered with this patch applied as it is.

In particular, a reset occurs after pci_ivshmem_init runs, so the
msix_entry_used array is reset to 0s, which causes the interrupt
delivery to fail.

If I comment out the msix_reset(), then interrupts are delivered.
Would the reset be caused by a bug in the guest driver?  or do I need
to reconfigure the msix after reset?  I'm unclear as to the proper
behaviour after a reset.

Thanks,
Cam

>
> -->
>
> ivshmem: add missing msix calls
>
> ivshmem used msix but didn't call it on either reset or
> config write paths. This used to partically work since
> guests don't use all of msi-x configuration fields,
> and reset is rarely used, but the patch 'msix: track function masked
> in pci device state' broke that. Fix by adding appropriate calls.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> --
>
> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
> index 242fbea..3680c0f 100644
> --- a/hw/ivshmem.c
> +++ b/hw/ivshmem.c
> @@ -505,6 +505,7 @@ static void ivshmem_reset(DeviceState *d)
>     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
>
>     s->intrstatus = 0;
> +    msix_reset(&s->dev);
>     return;
>  }
>
> @@ -610,6 +611,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
>     return 0;
>  }
>
> +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
> +                                uint32_t val, int len)
> +{
> +    pci_default_write_config(pci_dev, address, val, len);
> +    msix_write_config(pci_dev, address, val, len);
> +}
> +
>  static int pci_ivshmem_init(PCIDevice *dev)
>  {
>     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> @@ -734,6 +742,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
>
>     }
>
> +    s->dev.config_write = ivshmem_write_config;
> +
>     return 0;
>  }
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-04 23:47       ` Cam Macdonell
@ 2011-12-05  9:08         ` Michael S. Tsirkin
  2011-12-05 19:25           ` Cam Macdonell
  2011-12-05 19:48         ` [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls Michael S. Tsirkin
  1 sibling, 1 reply; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-12-05  9:08 UTC (permalink / raw)
  To: Cam Macdonell
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

On Sun, Dec 04, 2011 at 04:47:17PM -0700, Cam Macdonell wrote:
> On Sun, Dec 4, 2011 at 3:20 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
> >> Based on a git bisect, this patch breaks msi-x interrupt delivery in
> >> the ivshmem device.
> >
> > I think the following should fix it. Compiled-only -
> > could you pls check? If yes let's apply to the stable branch.
> 
> Thanks for the patch Michael.
> 
> It addresses the need for msix_write_config() to be called, but the
> addition of the msix_reset() is causing a reset of the vectors after
> they've been initialized in pci_ivshmem_init().  So, interrupts still
> aren't delivered with this patch applied as it is.
> 
> In particular, a reset occurs after pci_ivshmem_init runs, so the
> msix_entry_used array is reset to 0s, which causes the interrupt
> delivery to fail.
> 
> If I comment out the msix_reset(), then interrupts are delivered.
> Would the reset be caused by a bug in the guest driver?  or do I need
> to reconfigure the msix after reset?  I'm unclear as to the proper
> behaviour after a reset.
> 
> Thanks,
> Cam
> 

I didn't anticipate this, virtio only configures vectors when msi-x is enabled.
For 1.0 it's safest to do the same and just re-enable after reset.

So we'll end up with something like the following - does it help?

Side note: exit(1) is not the best way to handle
errors in the init function. I think you should add error_report, then
goto err on failures to init, cleanup what you have set up
meanwhile and return an error code.

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 242fbea..c58f4d3 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -500,11 +500,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     return;
 }
 
+/* Select the MSI-X vectors used by device.
+ * ivshmem maps events to vectors statically, so
+ * we just enable all vectors on init and after reset. */
+static void ivshmem_use_msix(IVShmemState * s)
+{
+    int i;
+
+    if (!msix_present(&s->dev)) {
+        return;
+    }
+
+    for (i = 0; i < s->vectors; i++) {
+        msix_vector_use(&s->dev, i);
+    }
+}
+
 static void ivshmem_reset(DeviceState *d)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
 
     s->intrstatus = 0;
+    msix_reset(&s->dev);
+    ivshmem_use_msix(s);
     return;
 }
 
@@ -535,12 +553,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) {
     return value;
 }
 
-static void ivshmem_setup_msi(IVShmemState * s) {
-
-    int i;
-
-    /* allocate the MSI-X vectors */
-
+static void ivshmem_setup_msi(IVShmemState * s)
+{
     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
         pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -551,13 +565,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
         exit(1);
     }
 
-    /* 'activate' the vectors */
-    for (i = 0; i < s->vectors; i++) {
-        msix_vector_use(&s->dev, i);
-    }
-
     /* allocate Qemu char devices for receiving interrupts */
     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
+
+    ivshmem_use_msix(s);
 }
 
 static void ivshmem_save(QEMUFile* f, void *opaque)
@@ -610,6 +621,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
     return 0;
 }
 
+static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
+				 uint32_t val, int len)
+{
+    pci_default_write_config(pci_dev, address, val, len);
+    msix_write_config(pci_dev, address, val, len);
+}
+
 static int pci_ivshmem_init(PCIDevice *dev)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
@@ -734,6 +752,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     }
 
+    s->dev.config_write = ivshmem_write_config;
+
     return 0;
 }
 

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state
  2011-12-05  9:08         ` Michael S. Tsirkin
@ 2011-12-05 19:25           ` Cam Macdonell
  0 siblings, 0 replies; 17+ messages in thread
From: Cam Macdonell @ 2011-12-05 19:25 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

On Mon, Dec 5, 2011 at 2:08 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Sun, Dec 04, 2011 at 04:47:17PM -0700, Cam Macdonell wrote:
>> On Sun, Dec 4, 2011 at 3:20 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> > On Fri, Dec 02, 2011 at 04:34:21PM -0700, Cam Macdonell wrote:
>> >> Based on a git bisect, this patch breaks msi-x interrupt delivery in
>> >> the ivshmem device.
>> >
>> > I think the following should fix it. Compiled-only -
>> > could you pls check? If yes let's apply to the stable branch.
>>
>> Thanks for the patch Michael.
>>
>> It addresses the need for msix_write_config() to be called, but the
>> addition of the msix_reset() is causing a reset of the vectors after
>> they've been initialized in pci_ivshmem_init().  So, interrupts still
>> aren't delivered with this patch applied as it is.
>>
>> In particular, a reset occurs after pci_ivshmem_init runs, so the
>> msix_entry_used array is reset to 0s, which causes the interrupt
>> delivery to fail.
>>
>> If I comment out the msix_reset(), then interrupts are delivered.
>> Would the reset be caused by a bug in the guest driver?  or do I need
>> to reconfigure the msix after reset?  I'm unclear as to the proper
>> behaviour after a reset.
>>
>> Thanks,
>> Cam
>>
>
> I didn't anticipate this, virtio only configures vectors when msi-x is enabled.
> For 1.0 it's safest to do the same and just re-enable after reset.
>
> So we'll end up with something like the following - does it help?

Yes, this fixes interrupt delivery.

>
> Side note: exit(1) is not the best way to handle
> errors in the init function. I think you should add error_report, then
> goto err on failures to init, cleanup what you have set up
> meanwhile and return an error code.

Thanks, I'll fix that.

>
> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
> index 242fbea..c58f4d3 100644
> --- a/hw/ivshmem.c
> +++ b/hw/ivshmem.c
> @@ -500,11 +500,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
>     return;
>  }
>
> +/* Select the MSI-X vectors used by device.
> + * ivshmem maps events to vectors statically, so
> + * we just enable all vectors on init and after reset. */
> +static void ivshmem_use_msix(IVShmemState * s)
> +{
> +    int i;
> +
> +    if (!msix_present(&s->dev)) {
> +        return;
> +    }
> +
> +    for (i = 0; i < s->vectors; i++) {
> +        msix_vector_use(&s->dev, i);
> +    }
> +}
> +
>  static void ivshmem_reset(DeviceState *d)
>  {
>     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
>
>     s->intrstatus = 0;
> +    msix_reset(&s->dev);
> +    ivshmem_use_msix(s);
>     return;
>  }
>
> @@ -535,12 +553,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) {
>     return value;
>  }
>
> -static void ivshmem_setup_msi(IVShmemState * s) {
> -
> -    int i;
> -
> -    /* allocate the MSI-X vectors */
> -
> +static void ivshmem_setup_msi(IVShmemState * s)
> +{
>     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
>     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
>         pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
> @@ -551,13 +565,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
>         exit(1);
>     }
>
> -    /* 'activate' the vectors */
> -    for (i = 0; i < s->vectors; i++) {
> -        msix_vector_use(&s->dev, i);
> -    }
> -
>     /* allocate Qemu char devices for receiving interrupts */
>     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
> +
> +    ivshmem_use_msix(s);
>  }
>
>  static void ivshmem_save(QEMUFile* f, void *opaque)
> @@ -610,6 +621,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
>     return 0;
>  }
>
> +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
> +                                uint32_t val, int len)
> +{
> +    pci_default_write_config(pci_dev, address, val, len);
> +    msix_write_config(pci_dev, address, val, len);
> +}
> +
>  static int pci_ivshmem_init(PCIDevice *dev)
>  {
>     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> @@ -734,6 +752,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
>
>     }
>
> +    s->dev.config_write = ivshmem_write_config;
> +
>     return 0;
>  }
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls
  2011-12-04 23:47       ` Cam Macdonell
  2011-12-05  9:08         ` Michael S. Tsirkin
@ 2011-12-05 19:48         ` Michael S. Tsirkin
  2012-01-13 22:43           ` Cam Macdonell
  1 sibling, 1 reply; 17+ messages in thread
From: Michael S. Tsirkin @ 2011-12-05 19:48 UTC (permalink / raw)
  To: Cam Macdonell
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

ivshmem used msix but didn't call it on either reset or
config write paths. This used to partically work since
guests don't use all of msi-x configuration fields,
and reset is rarely used, but the patch 'msix: track function masked
in pci device state' broke that. Fix by adding appropriate calls.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reported-by: Cam Macdonell <cam@cs.ualberta.ca>
Tested-by: Cam Macdonell <cam@cs.ualberta.ca>

---

Please apply the following to both master
and 1.0 stable branch. Thanks!

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 242fbea..c58f4d3 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -500,11 +500,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     return;
 }
 
+/* Select the MSI-X vectors used by device.
+ * ivshmem maps events to vectors statically, so
+ * we just enable all vectors on init and after reset. */
+static void ivshmem_use_msix(IVShmemState * s)
+{
+    int i;
+
+    if (!msix_present(&s->dev)) {
+        return;
+    }
+
+    for (i = 0; i < s->vectors; i++) {
+        msix_vector_use(&s->dev, i);
+    }
+}
+
 static void ivshmem_reset(DeviceState *d)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
 
     s->intrstatus = 0;
+    msix_reset(&s->dev);
+    ivshmem_use_msix(s);
     return;
 }
 
@@ -535,12 +553,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) {
     return value;
 }
 
-static void ivshmem_setup_msi(IVShmemState * s) {
-
-    int i;
-
-    /* allocate the MSI-X vectors */
-
+static void ivshmem_setup_msi(IVShmemState * s)
+{
     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
         pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -551,13 +565,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
         exit(1);
     }
 
-    /* 'activate' the vectors */
-    for (i = 0; i < s->vectors; i++) {
-        msix_vector_use(&s->dev, i);
-    }
-
     /* allocate Qemu char devices for receiving interrupts */
     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
+
+    ivshmem_use_msix(s);
 }
 
 static void ivshmem_save(QEMUFile* f, void *opaque)
@@ -610,6 +621,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
     return 0;
 }
 
+static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
+				 uint32_t val, int len)
+{
+    pci_default_write_config(pci_dev, address, val, len);
+    msix_write_config(pci_dev, address, val, len);
+}
+
 static int pci_ivshmem_init(PCIDevice *dev)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
@@ -734,6 +752,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     }
 
+    s->dev.config_write = ivshmem_write_config;
+
     return 0;
 }
 

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls
  2011-12-05 19:48         ` [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls Michael S. Tsirkin
@ 2012-01-13 22:43           ` Cam Macdonell
  2012-01-15 18:15             ` Andreas Färber
  0 siblings, 1 reply; 17+ messages in thread
From: Cam Macdonell @ 2012-01-13 22:43 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Blue Swirl, Jan Kiszka, Anthony Liguori, qemu-devel,
	Alexander Graf

Hello,

Can this patch be merged, please?

Thanks,
Cam

On Mon, Dec 5, 2011 at 12:48 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> ivshmem used msix but didn't call it on either reset or
> config write paths. This used to partically work since
> guests don't use all of msi-x configuration fields,
> and reset is rarely used, but the patch 'msix: track function masked
> in pci device state' broke that. Fix by adding appropriate calls.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Reported-by: Cam Macdonell <cam@cs.ualberta.ca>
> Tested-by: Cam Macdonell <cam@cs.ualberta.ca>
>
> ---
>
> Please apply the following to both master
> and 1.0 stable branch. Thanks!
>
> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
> index 242fbea..c58f4d3 100644
> --- a/hw/ivshmem.c
> +++ b/hw/ivshmem.c
> @@ -500,11 +500,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
>     return;
>  }
>
> +/* Select the MSI-X vectors used by device.
> + * ivshmem maps events to vectors statically, so
> + * we just enable all vectors on init and after reset. */
> +static void ivshmem_use_msix(IVShmemState * s)
> +{
> +    int i;
> +
> +    if (!msix_present(&s->dev)) {
> +        return;
> +    }
> +
> +    for (i = 0; i < s->vectors; i++) {
> +        msix_vector_use(&s->dev, i);
> +    }
> +}
> +
>  static void ivshmem_reset(DeviceState *d)
>  {
>     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
>
>     s->intrstatus = 0;
> +    msix_reset(&s->dev);
> +    ivshmem_use_msix(s);
>     return;
>  }
>
> @@ -535,12 +553,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) {
>     return value;
>  }
>
> -static void ivshmem_setup_msi(IVShmemState * s) {
> -
> -    int i;
> -
> -    /* allocate the MSI-X vectors */
> -
> +static void ivshmem_setup_msi(IVShmemState * s)
> +{
>     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
>     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
>         pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
> @@ -551,13 +565,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
>         exit(1);
>     }
>
> -    /* 'activate' the vectors */
> -    for (i = 0; i < s->vectors; i++) {
> -        msix_vector_use(&s->dev, i);
> -    }
> -
>     /* allocate Qemu char devices for receiving interrupts */
>     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
> +
> +    ivshmem_use_msix(s);
>  }
>
>  static void ivshmem_save(QEMUFile* f, void *opaque)
> @@ -610,6 +621,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
>     return 0;
>  }
>
> +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
> +                                uint32_t val, int len)
> +{
> +    pci_default_write_config(pci_dev, address, val, len);
> +    msix_write_config(pci_dev, address, val, len);
> +}
> +
>  static int pci_ivshmem_init(PCIDevice *dev)
>  {
>     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> @@ -734,6 +752,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
>
>     }
>
> +    s->dev.config_write = ivshmem_write_config;
> +
>     return 0;
>  }
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls
  2012-01-13 22:43           ` Cam Macdonell
@ 2012-01-15 18:15             ` Andreas Färber
  0 siblings, 0 replies; 17+ messages in thread
From: Andreas Färber @ 2012-01-15 18:15 UTC (permalink / raw)
  To: Cam Macdonell
  Cc: Anthony Liguori, Michael S. Tsirkin, Jan Kiszka, qemu-stable,
	qemu-devel, Alexander Graf, Blue Swirl

Am 13.01.2012 23:43, schrieb Cam Macdonell:
> Can this patch be merged, please?

You need to cc qemu-stable if you want it backported to v1.0.x once applied.

Andreas

> On Mon, Dec 5, 2011 at 12:48 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> ivshmem used msix but didn't call it on either reset or
>> config write paths. This used to partically work since
>> guests don't use all of msi-x configuration fields,
>> and reset is rarely used, but the patch 'msix: track function masked
>> in pci device state' broke that. Fix by adding appropriate calls.
>>
>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>> Reported-by: Cam Macdonell <cam@cs.ualberta.ca>
>> Tested-by: Cam Macdonell <cam@cs.ualberta.ca>
>>
>> ---
>>
>> Please apply the following to both master
>> and 1.0 stable branch. Thanks!
>>
>> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
>> index 242fbea..c58f4d3 100644
>> --- a/hw/ivshmem.c
>> +++ b/hw/ivshmem.c
>> @@ -500,11 +500,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
>>     return;
>>  }
>>
>> +/* Select the MSI-X vectors used by device.
>> + * ivshmem maps events to vectors statically, so
>> + * we just enable all vectors on init and after reset. */
>> +static void ivshmem_use_msix(IVShmemState * s)
>> +{
>> +    int i;
>> +
>> +    if (!msix_present(&s->dev)) {
>> +        return;
>> +    }
>> +
>> +    for (i = 0; i < s->vectors; i++) {
>> +        msix_vector_use(&s->dev, i);
>> +    }
>> +}
>> +
>>  static void ivshmem_reset(DeviceState *d)
>>  {
>>     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
>>
>>     s->intrstatus = 0;
>> +    msix_reset(&s->dev);
>> +    ivshmem_use_msix(s);
>>     return;
>>  }
>>
>> @@ -535,12 +553,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) {
>>     return value;
>>  }
>>
>> -static void ivshmem_setup_msi(IVShmemState * s) {
>> -
>> -    int i;
>> -
>> -    /* allocate the MSI-X vectors */
>> -
>> +static void ivshmem_setup_msi(IVShmemState * s)
>> +{
>>     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
>>     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
>>         pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
>> @@ -551,13 +565,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
>>         exit(1);
>>     }
>>
>> -    /* 'activate' the vectors */
>> -    for (i = 0; i < s->vectors; i++) {
>> -        msix_vector_use(&s->dev, i);
>> -    }
>> -
>>     /* allocate Qemu char devices for receiving interrupts */
>>     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
>> +
>> +    ivshmem_use_msix(s);
>>  }
>>
>>  static void ivshmem_save(QEMUFile* f, void *opaque)
>> @@ -610,6 +621,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
>>     return 0;
>>  }
>>
>> +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
>> +                                uint32_t val, int len)
>> +{
>> +    pci_default_write_config(pci_dev, address, val, len);
>> +    msix_write_config(pci_dev, address, val, len);
>> +}
>> +
>>  static int pci_ivshmem_init(PCIDevice *dev)
>>  {
>>     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
>> @@ -734,6 +752,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
>>
>>     }
>>
>> +    s->dev.config_write = ivshmem_write_config;
>> +
>>     return 0;
>>  }
>>

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-01-15 18:17 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-21 16:56 [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Michael S. Tsirkin
2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 1/3] msix: track function masked in pci device state Michael S. Tsirkin
2011-12-02 23:34   ` Cam Macdonell
2011-12-03 10:46     ` Jan Kiszka
2011-12-04 10:08     ` Michael S. Tsirkin
2011-12-04 10:20     ` Michael S. Tsirkin
2011-12-04 12:35       ` Jan Kiszka
2011-12-04 13:03         ` Michael S. Tsirkin
2011-12-04 23:47       ` Cam Macdonell
2011-12-05  9:08         ` Michael S. Tsirkin
2011-12-05 19:25           ` Cam Macdonell
2011-12-05 19:48         ` [Qemu-devel] [PATCH master/v1.0.x] ivshmem: add missing msix calls Michael S. Tsirkin
2012-01-13 22:43           ` Cam Macdonell
2012-01-15 18:15             ` Andreas Färber
2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 2/3] msix: Prevent bogus mask updates on MMIO accesses Michael S. Tsirkin
2011-11-21 16:57 ` [Qemu-devel] [PATCH for v1.0 3/3] msix: avoid mask updates if mask is unchanged Michael S. Tsirkin
2011-11-22  0:23 ` [Qemu-devel] [PATCH for v1.0 0/3] msix: fixes for 1.0 Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.