* [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
* 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
* [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
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.