Message ID | 20111204102036.GB15464@redhat.com |
---|---|
State | New |
Headers | show |
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
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.
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; > } > >
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; }